diff options
author | Douwe Maan <douwe@gitlab.com> | 2015-12-18 10:03:34 +0100 |
---|---|---|
committer | Douwe Maan <douwe@gitlab.com> | 2015-12-18 10:03:34 +0100 |
commit | d9c82d679fd622aead99aeb90369361a05e02a36 (patch) | |
tree | 6bc7986aafad7e0a3998c0a026573e9baf0cc032 /app/controllers | |
parent | 110a5f9c96457ac314f30630735dd827d9d96a4c (diff) | |
download | gitlab-ce-d9c82d679fd622aead99aeb90369361a05e02a36.tar.gz |
Automatically fork a project when not allowed to edit a file.
Diffstat (limited to 'app/controllers')
-rw-r--r-- | app/controllers/concerns/creates_commit.rb | 103 | ||||
-rw-r--r-- | app/controllers/concerns/creates_merge_request_for_commit.rb | 28 | ||||
-rw-r--r-- | app/controllers/projects/blob_controller.rb | 94 | ||||
-rw-r--r-- | app/controllers/projects/forks_controller.rb | 19 | ||||
-rw-r--r-- | app/controllers/projects/imports_controller.rb | 24 | ||||
-rw-r--r-- | app/controllers/projects/tree_controller.rb | 38 |
6 files changed, 158 insertions, 148 deletions
diff --git a/app/controllers/concerns/creates_commit.rb b/app/controllers/concerns/creates_commit.rb new file mode 100644 index 00000000000..62127a09081 --- /dev/null +++ b/app/controllers/concerns/creates_commit.rb @@ -0,0 +1,103 @@ +module CreatesCommit + extend ActiveSupport::Concern + + def create_commit(service, success_path:, failure_path:, failure_view: nil, success_notice: nil) + set_commit_variables + + commit_params = @commit_params.merge( + source_project: @project, + source_branch: @ref, + target_branch: @target_branch + ) + + result = service.new(@tree_edit_project, current_user, commit_params).execute + + if result[:status] == :success + flash[:notice] = success_notice || "Your changes have been successfully committed." + + if create_merge_request? + success_path = new_merge_request_path + target = different_project? ? "project" : "branch" + flash[:notice] << " You can now submit a merge request to get this change into the original #{target}." + end + + respond_to do |format| + format.html { redirect_to success_path } + format.json { render json: { message: "success", filePath: success_path } } + end + else + flash[:alert] = result[:message] + respond_to do |format| + format.html do + if failure_view + render failure_view + else + redirect_to failure_path + end + end + format.json { render json: { message: "failed", filePath: failure_path } } + end + end + end + + def authorize_edit_tree! + return if can?(current_user, :push_code, project) + return if current_user && current_user.already_forked?(project) + + access_denied! + end + + private + + def new_merge_request_path + new_namespace_project_merge_request_path( + @mr_source_project.namespace, + @mr_source_project, + merge_request: { + source_project_id: @mr_source_project.id, + target_project_id: @mr_target_project.id, + source_branch: @mr_source_branch, + target_branch: @mr_target_branch + } + ) + end + + def different_project? + @mr_source_project != @mr_target_project + end + + def different_branch? + @mr_source_branch != @mr_target_branch || different_project? + end + + def create_merge_request? + params[:create_merge_request].present? && different_branch? + end + + def set_commit_variables + @mr_source_branch = @target_branch + + if can?(current_user, :push_code, @project) + # Edit file in this project + @tree_edit_project = @project + @mr_source_project = @project + + if @project.forked? + # Merge request from this project to fork origin + @mr_target_project = @project.forked_from_project + @mr_target_branch = @mr_target_project.repository.root_ref + else + # Merge request to this project + @mr_target_project = @project + @mr_target_branch = @ref + end + else + # Edit file in fork + @tree_edit_project = current_user.fork_of(@project) + # Merge request from fork to this project + @mr_source_project = @tree_edit_project + @mr_target_project = @project + @mr_target_branch = @mr_target_project.repository.root_ref + end + end +end diff --git a/app/controllers/concerns/creates_merge_request_for_commit.rb b/app/controllers/concerns/creates_merge_request_for_commit.rb deleted file mode 100644 index c7527822158..00000000000 --- a/app/controllers/concerns/creates_merge_request_for_commit.rb +++ /dev/null @@ -1,28 +0,0 @@ -module CreatesMergeRequestForCommit - extend ActiveSupport::Concern - - def new_merge_request_path - if @project.forked? - target_project = @project.forked_from_project || @project - target_branch = target_project.repository.root_ref - else - target_project = @project - target_branch = @ref - end - - new_namespace_project_merge_request_path( - @project.namespace, - @project, - merge_request: { - source_project_id: @project.id, - target_project_id: target_project.id, - source_branch: @new_branch, - target_branch: target_branch - } - ) - end - - def create_merge_request? - params[:create_merge_request] && @new_branch != @ref - end -end diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb index 62163682936..c56a3497bb2 100644 --- a/app/controllers/projects/blob_controller.rb +++ b/app/controllers/projects/blob_controller.rb @@ -1,7 +1,7 @@ # Controller for viewing a file's blame class Projects::BlobController < Projects::ApplicationController include ExtractsPath - include CreatesMergeRequestForCommit + include CreatesCommit include ActionView::Helpers::SanitizeHelper # Raised when given an invalid file path @@ -9,21 +9,21 @@ class Projects::BlobController < Projects::ApplicationController before_action :require_non_empty_project, except: [:new, :create] before_action :authorize_download_code! - before_action :authorize_push_code!, only: [:destroy, :create] + before_action :authorize_edit_tree!, only: [:new, :create, :edit, :update, :destroy] before_action :assign_blob_vars before_action :commit, except: [:new, :create] before_action :blob, except: [:new, :create] before_action :from_merge_request, only: [:edit, :update] before_action :require_branch_head, only: [:edit, :update] before_action :editor_variables, except: [:show, :preview, :diff] - before_action :after_edit_path, only: [:edit, :update] def new commit unless @repository.empty? end def create - create_commit(Files::CreateService, success_path: after_create_path, + create_commit(Files::CreateService, success_notice: "The file has been successfully created.", + success_path: namespace_project_blob_path(@project.namespace, @project, File.join(@target_branch, @file_path)), failure_view: :new, failure_path: namespace_project_new_blob_path(@project.namespace, @project, @ref)) end @@ -36,6 +36,14 @@ class Projects::BlobController < Projects::ApplicationController end def update + after_edit_path = + if from_merge_request && @target_branch == @ref + diffs_namespace_project_merge_request_path(from_merge_request.target_project.namespace, from_merge_request.target_project, from_merge_request) + + "#file-path-#{hexdigest(@path)}" + else + namespace_project_blob_path(@project.namespace, @project, File.join(@target_branch, @path)) + end + create_commit(Files::UpdateService, success_path: after_edit_path, failure_view: :edit, failure_path: namespace_project_blob_path(@project.namespace, @project, @id)) @@ -50,15 +58,10 @@ class Projects::BlobController < Projects::ApplicationController end def destroy - result = Files::DeleteService.new(@project, current_user, @commit_params).execute - - if result[:status] == :success - flash[:notice] = "Your changes have been successfully committed" - redirect_to after_destroy_path - else - flash[:alert] = result[:message] - render :show - end + create_commit(Files::DeleteService, success_notice: "The file has been successfully deleted.", + success_path: namespace_project_tree_path(@project.namespace, @project, @target_branch), + failure_view: :show, + failure_path: namespace_project_blob_path(@project.namespace, @project, @id)) end def diff @@ -108,74 +111,13 @@ class Projects::BlobController < Projects::ApplicationController render_404 end - def create_commit(service, success_path:, failure_view:, failure_path:) - result = service.new(@project, current_user, @commit_params).execute - - if result[:status] == :success - flash[:notice] = "Your changes have been successfully committed" - respond_to do |format| - format.html { redirect_to success_path } - format.json { render json: { message: "success", filePath: success_path } } - end - else - flash[:alert] = result[:message] - respond_to do |format| - format.html { render failure_view } - format.json { render json: { message: "failed", filePath: failure_path } } - end - end - end - - def after_create_path - @after_create_path ||= - if create_merge_request? - new_merge_request_path - else - namespace_project_blob_path(@project.namespace, @project, File.join(@new_branch, @file_path)) - end - end - - def after_edit_path - @after_edit_path ||= - if create_merge_request? - new_merge_request_path - elsif from_merge_request && @new_branch == @ref - diffs_namespace_project_merge_request_path(from_merge_request.target_project.namespace, from_merge_request.target_project, from_merge_request) + - "#file-path-#{hexdigest(@path)}" - else - namespace_project_blob_path(@project.namespace, @project, File.join(@new_branch, @path)) - end - end - - def after_destroy_path - @after_destroy_path ||= - if create_merge_request? - new_merge_request_path - else - namespace_project_tree_path(@project.namespace, @project, @new_branch) - end - end - def from_merge_request # If blob edit was initiated from merge request page @from_merge_request ||= MergeRequest.find_by(id: params[:from_merge_request_id]) end - def sanitized_new_branch_name - sanitize(strip_tags(params[:new_branch])) - end - def editor_variables - @current_branch = @ref - - @new_branch = - if params[:new_branch].present? - sanitized_new_branch_name - elsif ::Gitlab::GitAccess.new(current_user, @project).can_push_to_branch?(@ref) - @ref - else - @repository.next_patch_branch - end + @target_branch = params[:target_branch] @file_path = if action_name.to_s == 'create' @@ -194,8 +136,6 @@ class Projects::BlobController < Projects::ApplicationController @commit_params = { file_path: @file_path, - current_branch: @current_branch, - target_branch: @new_branch, commit_message: params[:commit_message], file_content: params[:content], file_content_encoding: params[:encoding] diff --git a/app/controllers/projects/forks_controller.rb b/app/controllers/projects/forks_controller.rb index 8a785076bb7..51181b8042e 100644 --- a/app/controllers/projects/forks_controller.rb +++ b/app/controllers/projects/forks_controller.rb @@ -13,16 +13,25 @@ class Projects::ForksController < Projects::ApplicationController @forked_project = ::Projects::ForkService.new(project, current_user, namespace: namespace).execute if @forked_project.saved? && @forked_project.forked? + continue_params[:notice] ||= "The project was successfully forked." + if @forked_project.import_in_progress? - redirect_to namespace_project_import_path(@forked_project.namespace, @forked_project) + redirect_to namespace_project_import_path(@forked_project.namespace, @forked_project, continue: continue_params) else - redirect_to( - namespace_project_path(@forked_project.namespace, @forked_project), - notice: 'Project was successfully forked.' - ) + if continue_params + redirect_to continue_params[:to], notice: continue_params[:notice] + else + redirect_to namespace_project_path(@forked_project.namespace, @forked_project) + end end else render :error end end + + private + + def continue_params + params[:continue].permit(:to, :notice, :notice_now) + end end diff --git a/app/controllers/projects/imports_controller.rb b/app/controllers/projects/imports_controller.rb index fb8788f0818..e9c9edd3a3c 100644 --- a/app/controllers/projects/imports_controller.rb +++ b/app/controllers/projects/imports_controller.rb @@ -1,7 +1,7 @@ class Projects::ImportsController < Projects::ApplicationController # Authorize before_action :authorize_admin_project! - before_action :require_no_repo + before_action :require_no_repo, except: :show before_action :redirect_if_progress, except: :show def new @@ -24,21 +24,31 @@ class Projects::ImportsController < Projects::ApplicationController end def show - unless @project.import_in_progress? - if @project.import_finished? - redirect_to(project_path(@project)) and return + if @project.repository_exists? || @project.import_finished? + if continue_params + redirect_to continue_params[:to], notice: continue_params[:notice] else - redirect_to(new_namespace_project_import_path(@project.namespace, - @project)) and return + redirect_to project_path(@project) end + elsif @project.import_failed? + redirect_to new_namespace_project_import_path(@project.namespace, @project) + else + if continue_params && continue_params[:notice_now] + flash.now[:notice] = continue_params[:notice_now] + end + # Render end end private + def continue_params + @continue_params ||= params[:continue].permit(:to, :notice, :notice_now) + end + def require_no_repo if @project.repository_exists? && !@project.import_in_progress? - redirect_to(namespace_project_path(@project.namespace, @project)) and return + redirect_to(namespace_project_path(@project.namespace, @project)) end end diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb index 8f272ad1281..4f78bde2d2d 100644 --- a/app/controllers/projects/tree_controller.rb +++ b/app/controllers/projects/tree_controller.rb @@ -1,14 +1,14 @@ # Controller for viewing a repository's file structure class Projects::TreeController < Projects::ApplicationController include ExtractsPath - include CreatesMergeRequestForCommit + include CreatesCommit include ActionView::Helpers::SanitizeHelper before_action :require_non_empty_project, except: [:new, :create] before_action :assign_ref_vars before_action :assign_dir_vars, only: [:create_dir] before_action :authorize_download_code! - before_action :authorize_push_code!, only: [:create_dir] + before_action :authorize_edit_tree!, only: [:create_dir] def show return render_404 unless @repository.commit(@ref) @@ -34,44 +34,20 @@ class Projects::TreeController < Projects::ApplicationController def create_dir return render_404 unless @commit_params.values.all? - begin - result = Files::CreateDirService.new(@project, current_user, @commit_params).execute - message = result[:message] - rescue => e - message = e.to_s - end - - if result && result[:status] == :success - flash[:notice] = "The directory has been successfully created" - respond_to do |format| - format.html { redirect_to after_create_dir_path } - end - else - flash[:alert] = message - respond_to do |format| - format.html { redirect_to namespace_project_blob_path(@project.namespace, @project, @new_branch) } - end - end + create_commit(Files::CreateDirService, success_notice: "The directory has been successfully created.", + success_path: namespace_project_blob_path(@project.namespace, @project, File.join(@target_branch, @dir_name)), + failure_path: namespace_project_tree_path(@project.namespace, @project, @ref)) end private def assign_dir_vars - @new_branch = params[:new_branch].present? ? sanitize(strip_tags(params[:new_branch])) : @ref + @target_branch = params[:target_branch] + @dir_name = File.join(@path, params[:dir_name]) @commit_params = { file_path: @dir_name, - current_branch: @ref, - target_branch: @new_branch, commit_message: params[:commit_message], } end - - def after_create_dir_path - if create_merge_request? - new_merge_request_path - else - namespace_project_blob_path(@project.namespace, @project, File.join(@new_branch, @dir_name)) - end - end end |