cirandas.net

commit e776c16864decb7ca4235d521995ad2de513ae0b

Author: Pedro Lucas Porcellis <porcellis@eletrotupi.com>

controllers/public: introduce antispam username and email blocklists

This patchset also includes a noosfero feature-flag to enable or disable
completely the antispam feature. It depends on the antispam project data
[1] to be available the installed on server. This is a rather simpler
system which does not depends on a more elaborated system as the
anti_spam plugin (which depends on Akismet and works only for comments).

[1]: https://git.eletrotupi.com/antispam

 app/controllers/public/account_controller.rb | 85 ++++++++++++---------
 config/noosfero.yml.dist | 1 


diff --git a/app/controllers/public/account_controller.rb b/app/controllers/public/account_controller.rb
index 3cc1fca8fdf5f99c53c1f7d6d54ec90e37bc136e..1d9cb05d5fb1c3e3479906a2bac88fd9c1601c64 100644
--- a/app/controllers/public/account_controller.rb
+++ b/app/controllers/public/account_controller.rb
@@ -110,9 +110,17 @@       @person.environment = @user.environment
       @kinds = environment.kinds.where(:type => 'Person')
 
       if request.post?
-        if email_domain_blocklist.include?(@user.email.split("@").last)
+        if NOOSFERO_CONF['enable_antispam_blocklist'] && email_domain_blocklist.include?(@user.email.split("@").last)
           session[:notice] = _('Email domain is on the block list!')
           render action: 'signup', status: :unprocessable_entity
+
+          return
+        end
+
+        if NOOSFERO_CONF['enable_antispam_blocklist'] && user.login.match(username_blocklist)
+          session[:notice] = _('Login contains words that are on the block list!')
+          render action: 'signup', status: :unprocessable_entity
+
           return
         end
 
@@ -300,17 +308,23 @@   end
 
   def check_valid_name
     @identifier = params[:identifier]
-    valid = Person.is_available?(@identifier, environment)
-    if valid
-      @status = _('This login name is available')
-      @status_class = 'validated'
-    elsif !@identifier.empty?
-      @suggested_usernames = suggestion_based_on_username(@identifier)
-      @status = _('This login name is unavailable')
-      @status_class = 'invalid'
+
+    if NOOSFERO_CONF['enable_antispam_blocklist'] && @identifier.match(username_blocklist)
+      @status = _("This login name is blocked")
+      @status_class = "invalid"
     else
-      @status_class = 'invalid'
-      @status = _('This field can\'t be blank')
+      valid = Person.is_available?(@identifier, environment)
+      if valid
+        @status = _('This login name is available')
+        @status_class = 'validated'
+      elsif !@identifier.empty?
+        @suggested_usernames = suggestion_based_on_username(@identifier)
+        @status = _('This login name is unavailable')
+        @status_class = 'invalid'
+      else
+        @status_class = 'invalid'
+        @status = _('This field can\'t be blank')
+      end
     end
 
     respond_to do |format|
@@ -325,7 +339,7 @@
   end
 
   def check_email
-    if email_domain_blocklist.include?(params[:address].split("@").last)
+    if NOOSFERO_CONF['enable_antispam_blocklist'] && email_domain_blocklist.include?(params[:address].split("@").last)
       @status = _('This e-mail address domain is blocked')
       @status_class = 'invalid'
     else
@@ -410,31 +424,28 @@     Rails.cache.delete params[:signup_time_key] if params[:signup_time_key]
   end
 
   def email_domain_blocklist
-    [
-      "livingthere.com",
-      "click2mail.net",
-      "janmail.org",
-      "livingthere.org",
-      "virtualassistantdubai.com",
-      "tmpmail.org",
-      "tmails.ws",
-      "tmpmail.net",
-      "tmpmail.ws",
-      "bareed.ws",
-      "tmpbox.net",
-      "moakt.com",
-      "moakt.co",
-      "moakt.cc",
-      "moakt.ws",
-      "disbox.org",
-      "opencalls.com",
-      "opencalls.co",
-      "newsinyourpocket.com",
-      "kdmodel.com",
-      "seoexpartebd.com",
-      "litony.com",
-      "ouishare.us"
-    ]
+    # TODO: Read this from a environment variable?
+    begin
+      raw_data = File.read("/usr/share/antispam/domains.json")
+      domains = JSON.parse(raw_data)
+
+      return domains
+    rescue
+      return []
+    end
+  end
+
+  def username_blocklist
+    # TODO: Read this from a environment variable?
+    begin
+      raw_data = File.read("/usr/share/antispam/usernames.json")
+      domains = JSON.parse(raw_data)
+
+      return Regexp.new(domains.join("|"))
+    rescue
+      # XXX: That's a hack so we can get away from escaping on the caller
+      return Regexp.new(Time.now.to_s)
+    end
   end
 
   def may_be_a_bot




diff --git a/config/noosfero.yml.dist b/config/noosfero.yml.dist
index 84cdde06bc641c7e85ed9b5867a42bdb8d078e6b..42e5ff7ddabe5400c05ad8f1a9b0c82dd2171843 100644
--- a/config/noosfero.yml.dist
+++ b/config/noosfero.yml.dist
@@ -16,6 +16,7 @@   api_recaptcha_site_key:      '6LdsWAcTAAAAAChTUUD6yu9fCDhdIZzNd7F53zf-'
   api_recaptcha_private_key:   '6LdsWAcTAAAAAB6maB_HalVyCc4asDAxPxloIMvY'
   api_recaptcha_verify_uri:    'https://www.google.com/recaptcha/api/siteverify'  
   delayed_attachment_fallback_original_image: false
+  enable_antispam_blocklist: true
 
 test: