From 160bd862bede180faf66de7e5b09300347c24279 Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Tue, 5 Nov 2013 12:21:11 +0200
Subject: [PATCH] Refactoring for EditTree and NewTree controllers and contexts

Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
---
 app/contexts/files/update_context.rb          | 38 +++++++++++++++
 .../projects/application_controller.rb        |  6 +++
 .../projects/base_tree_controller.rb          |  8 ++++
 .../projects/edit_tree_controller.rb          | 47 ++++---------------
 .../projects/new_tree_controller.rb           |  9 +---
 app/controllers/projects/tree_controller.rb   |  9 +---
 6 files changed, 65 insertions(+), 52 deletions(-)
 create mode 100644 app/contexts/files/update_context.rb
 create mode 100644 app/controllers/projects/base_tree_controller.rb

diff --git a/app/contexts/files/update_context.rb b/app/contexts/files/update_context.rb
new file mode 100644
index 0000000000..000d3d02f1
--- /dev/null
+++ b/app/contexts/files/update_context.rb
@@ -0,0 +1,38 @@
+module Files
+  class UpdateContext < BaseContext
+    def execute
+      allowed = if project.protected_branch?(ref)
+                  can?(current_user, :push_code_to_protected_branches, project)
+                else
+                  can?(current_user, :push_code, project)
+                end
+
+      unless allowed
+        return error("You are not allowed to push into this branch")
+      end
+
+      unless repository.branch_names.include?(ref)
+        return error("You can only create files if you are on top of a branch")
+      end
+
+      blob = repository.blob_at(ref, path)
+
+      unless blob
+        return error("You can only edit text files")
+      end
+
+      new_file_action = Gitlab::Satellite::EditFileAction.new(current_user, project, ref, path)
+      created_successfully = new_file_action.commit!(
+        params[:content],
+        params[:commit_message],
+        params[:last_commit]
+      )
+
+      if created_successfully
+        success
+      else
+        error("Your changes could not be commited, because the file has been changed")
+      end
+    end
+  end
+end
diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb
index 8fd4565f36..80aeb5cd6c 100644
--- a/app/controllers/projects/application_controller.rb
+++ b/app/controllers/projects/application_controller.rb
@@ -23,4 +23,10 @@ class Projects::ApplicationController < ApplicationController
       'public_projects'
     end
   end
+
+  def require_branch_head
+    unless @repository.branch_names.include?(@ref)
+      redirect_to project_tree_path(@project, @ref), notice: "This action is not allowed unless you are on top of a branch"
+    end
+  end
 end
diff --git a/app/controllers/projects/base_tree_controller.rb b/app/controllers/projects/base_tree_controller.rb
new file mode 100644
index 0000000000..5e30593443
--- /dev/null
+++ b/app/controllers/projects/base_tree_controller.rb
@@ -0,0 +1,8 @@
+class Projects::BaseTreeController < Projects::ApplicationController
+  include ExtractsPath
+
+  before_filter :authorize_read_project!
+  before_filter :authorize_code_access!
+  before_filter :require_non_empty_project
+end
+
diff --git a/app/controllers/projects/edit_tree_controller.rb b/app/controllers/projects/edit_tree_controller.rb
index 0e51ff59f3..f6c547a020 100644
--- a/app/controllers/projects/edit_tree_controller.rb
+++ b/app/controllers/projects/edit_tree_controller.rb
@@ -1,53 +1,26 @@
-# Controller for edit a repository's file
-class Projects::EditTreeController < Projects::ApplicationController
-  include ExtractsPath
-
-  # Authorize
-  before_filter :authorize_read_project!
-  before_filter :authorize_code_access!
-  before_filter :require_non_empty_project
-
-  before_filter :edit_requirements, only: [:show, :update]
+class Projects::EditTreeController < Projects::BaseTreeController
+  before_filter :require_branch_head
+  before_filter :blob
 
   def show
     @last_commit = Gitlab::Git::Commit.last_for_path(@repository, @ref, @path).sha
   end
 
   def update
-    edit_file_action = Gitlab::Satellite::EditFileAction.new(current_user, @project, @ref, @path)
-    updated_successfully = edit_file_action.commit!(
-      params[:content],
-      params[:commit_message],
-      params[:last_commit]
-    )
+    result = Files::UpdateContext.new(@project, current_user, params, @ref, @path).execute
 
-    if updated_successfully
-      redirect_to project_blob_path(@project, @id), notice: "Your changes have been successfully commited"
+    if result[:status] == :success
+      flash[:notice] = "Your changes have been successfully commited"
+      redirect_to project_blob_path(@project, @id)
     else
-      flash[:notice] = "Your changes could not be commited, because the file has been changed"
+      flash[:alert] = result[:error]
       render :show
     end
   end
 
   private
 
-  def edit_requirements
-    @blob = @repository.blob_at(@commit.id, @path)
-
-    unless @blob
-      redirect_to project_blob_path(@project, @id), notice: "You can only edit text files"
-    end
-
-    allowed = if project.protected_branch? @ref
-                can?(current_user, :push_code_to_protected_branches, project)
-              else
-                can?(current_user, :push_code, project)
-              end
-
-    return access_denied! unless allowed
-
-    unless @repository.branch_names.include?(@ref)
-      redirect_to project_blob_path(@project, @id), notice: "You can only edit this file if you are on top of a branch"
-    end
+  def blob
+    @blob ||= @repository.blob_at(@commit.id, @path)
   end
 end
diff --git a/app/controllers/projects/new_tree_controller.rb b/app/controllers/projects/new_tree_controller.rb
index 684c916055..9f9e0191e9 100644
--- a/app/controllers/projects/new_tree_controller.rb
+++ b/app/controllers/projects/new_tree_controller.rb
@@ -1,10 +1,5 @@
-class Projects::NewTreeController < Projects::ApplicationController
-  include ExtractsPath
-
-  # Authorize
-  before_filter :authorize_read_project!
-  before_filter :authorize_code_access!
-  before_filter :require_non_empty_project
+class Projects::NewTreeController < Projects::BaseTreeController
+  before_filter :require_branch_head
 
   def show
   end
diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb
index 1150efbea9..30c94ec6da 100644
--- a/app/controllers/projects/tree_controller.rb
+++ b/app/controllers/projects/tree_controller.rb
@@ -1,12 +1,5 @@
 # Controller for viewing a repository's file structure
-class Projects::TreeController < Projects::ApplicationController
-  include ExtractsPath
-
-  # Authorize
-  before_filter :authorize_read_project!
-  before_filter :authorize_code_access!
-  before_filter :require_non_empty_project
-
+class Projects::TreeController < Projects::BaseTreeController
   def show
     return not_found! if tree.entries.empty?
 
-- 
2.30.9