From 891a1fe20d421067051e88120b8c91db9274ae4b Mon Sep 17 00:00:00 2001
From: Alex Shulgin <ash@commandprompt.com>
Date: Tue, 8 May 2012 13:24:06 -0700
Subject: [PATCH 21/25] Add --unknow-user=register option support to mail handler.

---
 app/controllers/account_controller.rb |   78 ++++++++-------------------------
 app/models/mail_handler.rb            |    5 +-
 app/models/user.rb                    |   27 +++++++++++
 extra/mail_handler/rdm-mailhandler.rb |    3 +-
 4 files changed, 51 insertions(+), 62 deletions(-)

diff --git a/app/controllers/account_controller.rb b/app/controllers/account_controller.rb
index 926e044..de14909 100644
--- a/app/controllers/account_controller.rb
+++ b/app/controllers/account_controller.rb
@@ -102,14 +102,7 @@ class AccountController < ApplicationController
         @user.login = params[:user][:login]
         @user.password, @user.password_confirmation = params[:user][:password], params[:user][:password_confirmation]
 
-        case Setting.self_registration
-        when '1'
-          register_by_email_activation(@user)
-        when '3'
-          register_automatically(@user)
-        else
-          register_manually_by_administrator(@user)
-        end
+        process_user_registration(@user)
       end
     end
   end
@@ -167,19 +160,8 @@ class AccountController < ApplicationController
           user.random_password
           user.register
 
-          case Setting.self_registration
-          when '1'
-            register_by_email_activation(user) do
-              onthefly_creation_failed(user)
-            end
-          when '3'
-            register_automatically(user) do
-              onthefly_creation_failed(user)
-            end
-          else
-            register_manually_by_administrator(user) do
-              onthefly_creation_failed(user)
-            end
+          process_user_registration(user) do
+            onthefly_creation_failed(user)
           end
         else
           # Existing record
@@ -229,44 +211,22 @@ class AccountController < ApplicationController
     flash.now[:error] = l(:notice_account_invalid_creditentials)
   end
 
-  # Register a user for email activation.
-  #
-  # Pass a block for behavior when a user fails to save
-  def register_by_email_activation(user, &block)
-    token = Token.new(:user => user, :action => "register")
-    if user.save and token.save
-      Mailer.deliver_register(token)
-      flash[:notice] = l(:notice_account_register_done)
-      redirect_to :action => 'login'
-    else
-      yield if block_given?
-    end
-  end
-
-  # Automatically register a user
-  #
-  # Pass a block for behavior when a user fails to save
-  def register_automatically(user, &block)
-    # Automatic activation
-    user.activate
-    user.last_login_on = Time.now
-    if user.save
-      self.logged_user = user
-      flash[:notice] = l(:notice_account_activated)
-      redirect_to :controller => 'my', :action => 'account'
-    else
-      yield if block_given?
-    end
-  end
-
-  # Manual activation by the administrator
-  #
-  # Pass a block for behavior when a user fails to save
-  def register_manually_by_administrator(user, &block)
-    if user.save
-      # Sends an email to the administrators
-      Mailer.deliver_account_activation_request(user)
-      account_pending
+  def process_user_registration(user, &block)
+    if user.process_registration
+      case Setting.self_registration
+      when '1'
+        # mail activation
+        flash[:notice] = l(:notice_account_register_done)
+        redirect_to :action => 'login'
+      when '3'
+        # auto activation
+        self.logged_user = user
+        flash[:notice] = l(:notice_account_activated)
+        redirect_to :controller => 'my', :action => 'account'
+      else
+        # admin approval
+        account_pending
+      end
     else
       yield if block_given?
     end
diff --git a/app/models/mail_handler.rb b/app/models/mail_handler.rb
index 131f7df..305d70a 100644
--- a/app/models/mail_handler.rb
+++ b/app/models/mail_handler.rb
@@ -85,7 +85,7 @@ class MailHandler < ActionMailer::Base
       case @@handler_options[:unknown_user]
       when 'accept'
         @user = User.anonymous
-      when 'create'
+      when 'create', 'register'
         @user = create_user_from_email
         if @user
           logger.info "MailHandler: [#{@user.login}] account created"
@@ -376,6 +376,7 @@ class MailHandler < ActionMailer::Base
   # Returns a User from an email address and a full name
   def self.new_user_from_attributes(email_address, fullname=nil)
     user = User.new
+    user.register if @@handler_options[:unknown_user] == 'register'
 
     # Truncating the email address would result in an invalid format
     user.mail = email_address
@@ -405,7 +406,7 @@ class MailHandler < ActionMailer::Base
     addr = email.from_addrs.to_a.first
     if addr && !addr.spec.blank?
       user = self.class.new_user_from_attributes(addr.spec, TMail::Unquoter.unquote_and_convert_to(addr.name, 'utf-8'))
-      if user.save
+      if user.process_registration
         user
       else
         logger.error "MailHandler: failed to create User: #{user.errors.full_messages}"
diff --git a/app/models/user.rb b/app/models/user.rb
index e522619..e827f65 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -381,6 +381,17 @@ class User < Principal
     !logged?
   end
 
+  def process_registration
+    case Setting.self_registration
+    when '1'
+      register_by_email_activation
+    when '3'
+      register_automatically
+    else
+      register_manually_by_administrator
+    end
+  end
+
   # Return user's roles for project
   def roles_for_project(project)
     roles = []
@@ -597,6 +608,22 @@ class User < Principal
 
   private
 
+  def register_by_email_activation
+    token = Token.new(:user => self, :action => "register")
+    Mailer.deliver_register(token) if self.save and token.save
+  end
+
+  def register_automatically
+    self.activate
+    self.last_login_on = Time.now
+    self.save
+  end
+
+  def register_manually_by_administrator
+    # Sends an email to the administrators
+    Mailer.deliver_account_activation_request(self) if self.save
+  end
+
   # Removes references that are not handled by associations
   # Things that are not deleted are reassociated with the anonymous user
   def remove_references_before_destroy
diff --git a/extra/mail_handler/rdm-mailhandler.rb b/extra/mail_handler/rdm-mailhandler.rb
index a04ef05..f799f81 100644
--- a/extra/mail_handler/rdm-mailhandler.rb
+++ b/extra/mail_handler/rdm-mailhandler.rb
@@ -44,7 +44,8 @@ class RedmineMailHandler
                                               "ACTION can be one of the following values:",
                                               "* ignore: email is ignored (default)",
                                               "* accept: accept as anonymous user",
-                                              "* create: create a user account") {|v| self.unknown_user = v}
+                                              "* create: create a user account"
+                                              "* register: create an inactive user account") {|v| self.unknown_user = v}
       opts.on("--no-permission-check",        "disable permission checking when receiving",
                                               "the email") {self.no_permission_check = '1'}
       opts.on("--no-account-notice",          "disable new user account notification") {self.no_account_notice = '1'}
-- 
1.7.0.4

