diff options
Diffstat (limited to 'app/controllers')
18 files changed, 361 insertions, 152 deletions
diff --git a/app/controllers/admin/hooks_controller.rb b/app/controllers/admin/hooks_controller.rb index cbfc4581411..a119934febc 100644 --- a/app/controllers/admin/hooks_controller.rb +++ b/app/controllers/admin/hooks_controller.rb @@ -1,4 +1,6 @@ class Admin::HooksController < Admin::ApplicationController + before_action :hook, only: :edit + def index @hooks = SystemHook.all @hook = SystemHook.new @@ -15,15 +17,25 @@ class Admin::HooksController < Admin::ApplicationController end end + def edit + end + + def update + if hook.update_attributes(hook_params) + flash[:notice] = 'System hook was successfully updated.' + redirect_to admin_hooks_path + else + render 'edit' + end + end + def destroy - @hook = SystemHook.find(params[:id]) - @hook.destroy + hook.destroy redirect_to admin_hooks_path end def test - @hook = SystemHook.find(params[:hook_id]) data = { event_name: "project_create", name: "Ruby", @@ -32,11 +44,17 @@ class Admin::HooksController < Admin::ApplicationController owner_name: "Someone", owner_email: "example@gitlabhq.com" } - @hook.execute(data, 'system_hooks') + hook.execute(data, 'system_hooks') redirect_back_or_default end + private + + def hook + @hook ||= SystemHook.find(params[:id]) + end + def hook_params params.require(:hook).permit( :enable_ssl_verification, diff --git a/app/controllers/concerns/milestone_actions.rb b/app/controllers/concerns/milestone_actions.rb new file mode 100644 index 00000000000..3e2a0fe4f8b --- /dev/null +++ b/app/controllers/concerns/milestone_actions.rb @@ -0,0 +1,53 @@ +module MilestoneActions + extend ActiveSupport::Concern + + def merge_requests + respond_to do |format| + format.html { redirect_to milestone_redirect_path } + format.json do + render json: tabs_json("shared/milestones/_merge_requests_tab", { + merge_requests: @milestone.merge_requests, + show_project_name: true + }) + end + end + end + + def participants + respond_to do |format| + format.html { redirect_to milestone_redirect_path } + format.json do + render json: tabs_json("shared/milestones/_participants_tab", { + users: @milestone.participants + }) + end + end + end + + def labels + respond_to do |format| + format.html { redirect_to milestone_redirect_path } + format.json do + render json: tabs_json("shared/milestones/_labels_tab", { + labels: @milestone.labels + }) + end + end + end + + private + + def tabs_json(partial, data = {}) + { + html: view_to_html_string(partial, data) + } + end + + def milestone_redirect_path + if @project + namespace_project_milestone_path(@project.namespace, @project, @milestone) + else + group_milestone_path(@group, @milestone.safe_title, title: @milestone.title) + end + end +end diff --git a/app/controllers/concerns/notes_actions.rb b/app/controllers/concerns/notes_actions.rb new file mode 100644 index 00000000000..c32038d07bf --- /dev/null +++ b/app/controllers/concerns/notes_actions.rb @@ -0,0 +1,136 @@ +module NotesActions + include RendersNotes + extend ActiveSupport::Concern + + included do + before_action :authorize_admin_note!, only: [:update, :destroy] + end + + def index + current_fetched_at = Time.now.to_i + + notes_json = { notes: [], last_fetched_at: current_fetched_at } + + @notes = notes_finder.execute.inc_relations_for_view + @notes = prepare_notes_for_rendering(@notes) + + @notes.each do |note| + next if note.cross_reference_not_visible_for?(current_user) + + notes_json[:notes] << note_json(note) + end + + render json: notes_json + end + + def create + create_params = note_params.merge( + merge_request_diff_head_sha: params[:merge_request_diff_head_sha], + in_reply_to_discussion_id: params[:in_reply_to_discussion_id] + ) + @note = Notes::CreateService.new(project, current_user, create_params).execute + + if @note.is_a?(Note) + Banzai::NoteRenderer.render([@note], @project, current_user) + end + + respond_to do |format| + format.json { render json: note_json(@note) } + format.html { redirect_back_or_default } + end + end + + def update + @note = Notes::UpdateService.new(project, current_user, note_params).execute(note) + + if @note.is_a?(Note) + Banzai::NoteRenderer.render([@note], @project, current_user) + end + + respond_to do |format| + format.json { render json: note_json(@note) } + format.html { redirect_back_or_default } + end + end + + def destroy + if note.editable? + Notes::DestroyService.new(project, current_user).execute(note) + end + + respond_to do |format| + format.js { head :ok } + end + end + + private + + def note_json(note) + attrs = { + commands_changes: note.commands_changes + } + + if note.persisted? + attrs.merge!( + valid: true, + id: note.id, + discussion_id: note.discussion_id(noteable), + html: note_html(note), + note: note.note + ) + + discussion = note.to_discussion(noteable) + unless discussion.individual_note? + attrs.merge!( + discussion_resolvable: discussion.resolvable?, + + diff_discussion_html: diff_discussion_html(discussion), + discussion_html: discussion_html(discussion) + ) + end + else + attrs.merge!( + valid: false, + errors: note.errors + ) + end + + attrs + end + + def authorize_admin_note! + return access_denied! unless can?(current_user, :admin_note, note) + end + + def note_params + params.require(:note).permit( + :project_id, + :noteable_type, + :noteable_id, + :commit_id, + :noteable, + :type, + + :note, + :attachment, + + # LegacyDiffNote + :line_code, + + # DiffNote + :position + ) + end + + def noteable + @noteable ||= notes_finder.target + end + + def last_fetched_at + request.headers['X-Last-Fetched-At'] + end + + def notes_finder + @notes_finder ||= NotesFinder.new(project, current_user, finder_params) + end +end diff --git a/app/controllers/concerns/renders_blob.rb b/app/controllers/concerns/renders_blob.rb index d478c3bb6ca..9faf68e6d97 100644 --- a/app/controllers/concerns/renders_blob.rb +++ b/app/controllers/concerns/renders_blob.rb @@ -14,4 +14,8 @@ module RendersBlob html: view_to_html_string("projects/blob/_viewer", viewer: viewer, load_asynchronously: false) } end + + def override_max_blob_size(blob) + blob.override_max_size! if params[:override_max_size] == 'true' + end end diff --git a/app/controllers/concerns/renders_notes.rb b/app/controllers/concerns/renders_notes.rb index dd21066ac13..41c3114ad1e 100644 --- a/app/controllers/concerns/renders_notes.rb +++ b/app/controllers/concerns/renders_notes.rb @@ -10,6 +10,8 @@ module RendersNotes private def preload_max_access_for_authors(notes, project) + return nil unless project + user_ids = notes.map(&:author_id) project.team.max_member_access_for_user_ids(user_ids) end diff --git a/app/controllers/concerns/service_params.rb b/app/controllers/concerns/service_params.rb index a8c0937569c..be2e6c7f193 100644 --- a/app/controllers/concerns/service_params.rb +++ b/app/controllers/concerns/service_params.rb @@ -38,6 +38,7 @@ module ServiceParams :new_issue_url, :notify, :notify_only_broken_pipelines, + :notify_only_default_branch, :password, :priority, :project_key, diff --git a/app/controllers/concerns/snippets_actions.rb b/app/controllers/concerns/snippets_actions.rb index ca6dffe1cc5..ffea712a833 100644 --- a/app/controllers/concerns/snippets_actions.rb +++ b/app/controllers/concerns/snippets_actions.rb @@ -5,10 +5,12 @@ module SnippetsActions end def raw + disposition = params[:inline] == 'false' ? 'attachment' : 'inline' + send_data( convert_line_endings(@snippet.content), type: 'text/plain; charset=utf-8', - disposition: 'inline', + disposition: disposition, filename: @snippet.sanitized_file_name ) end diff --git a/app/controllers/concerns/toggle_award_emoji.rb b/app/controllers/concerns/toggle_award_emoji.rb index fbf9a026b10..ba5b7d33f87 100644 --- a/app/controllers/concerns/toggle_award_emoji.rb +++ b/app/controllers/concerns/toggle_award_emoji.rb @@ -22,7 +22,8 @@ module ToggleAwardEmoji def to_todoable(awardable) case awardable when Note - awardable.noteable + # we don't create todos for personal snippet comments for now + awardable.for_personal_snippet? ? nil : awardable.noteable when MergeRequest, Issue awardable when Snippet diff --git a/app/controllers/groups/milestones_controller.rb b/app/controllers/groups/milestones_controller.rb index 43102596201..e52fa766044 100644 --- a/app/controllers/groups/milestones_controller.rb +++ b/app/controllers/groups/milestones_controller.rb @@ -1,6 +1,8 @@ class Groups::MilestonesController < Groups::ApplicationController + include MilestoneActions + before_action :group_projects - before_action :milestone, only: [:show, :update] + before_action :milestone, only: [:show, :update, :merge_requests, :participants, :labels] before_action :authorize_admin_milestones!, only: [:new, :create, :update] def index diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb index be5822b2cd4..9489bbddfc4 100644 --- a/app/controllers/projects/blob_controller.rb +++ b/app/controllers/projects/blob_controller.rb @@ -35,7 +35,7 @@ class Projects::BlobController < Projects::ApplicationController end def show - @blob.override_max_size! if params[:override_max_size] == 'true' + override_max_blob_size(@blob) respond_to do |format| format.html do diff --git a/app/controllers/projects/deployments_controller.rb b/app/controllers/projects/deployments_controller.rb new file mode 100644 index 00000000000..c319671456d --- /dev/null +++ b/app/controllers/projects/deployments_controller.rb @@ -0,0 +1,18 @@ +class Projects::DeploymentsController < Projects::ApplicationController + before_action :authorize_read_environment! + before_action :authorize_read_deployment! + + def index + deployments = environment.deployments.reorder(created_at: :desc) + deployments = deployments.where('created_at > ?', params[:after].to_time) if params[:after]&.to_time + + render json: { deployments: DeploymentSerializer.new(user: @current_user, project: project) + .represent_concise(deployments) } + end + + private + + def environment + @environment ||= project.environments.find(params[:environment_id]) + end +end diff --git a/app/controllers/projects/hooks_controller.rb b/app/controllers/projects/hooks_controller.rb index 1e41f980f31..86d13a0d222 100644 --- a/app/controllers/projects/hooks_controller.rb +++ b/app/controllers/projects/hooks_controller.rb @@ -1,6 +1,7 @@ class Projects::HooksController < Projects::ApplicationController # Authorize before_action :authorize_admin_project! + before_action :hook, only: :edit respond_to :html @@ -17,6 +18,18 @@ class Projects::HooksController < Projects::ApplicationController redirect_to namespace_project_settings_integrations_path(@project.namespace, @project) end + def edit + end + + def update + if hook.update_attributes(hook_params) + flash[:notice] = 'Hook was successfully updated.' + redirect_to namespace_project_settings_integrations_path(@project.namespace, @project) + else + render 'edit' + end + end + def test if !@project.empty_repo? status, message = TestHookService.new.execute(hook, current_user) diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb index d0dd524c484..c56bce19eee 100644 --- a/app/controllers/projects/milestones_controller.rb +++ b/app/controllers/projects/milestones_controller.rb @@ -1,12 +1,14 @@ class Projects::MilestonesController < Projects::ApplicationController + include MilestoneActions + before_action :module_enabled - before_action :milestone, only: [:edit, :update, :destroy, :show, :sort_issues, :sort_merge_requests] + before_action :milestone, only: [:edit, :update, :destroy, :show, :sort_issues, :sort_merge_requests, :merge_requests, :participants, :labels] # Allow read any milestone before_action :authorize_read_milestone! # Allow admin milestone - before_action :authorize_admin_milestone!, except: [:index, :show] + before_action :authorize_admin_milestone!, except: [:index, :show, :merge_requests, :participants, :labels] respond_to :html diff --git a/app/controllers/projects/notes_controller.rb b/app/controllers/projects/notes_controller.rb index 405ea3c0a4f..37f51b2ebe3 100644 --- a/app/controllers/projects/notes_controller.rb +++ b/app/controllers/projects/notes_controller.rb @@ -1,68 +1,22 @@ class Projects::NotesController < Projects::ApplicationController - include RendersNotes + include NotesActions include ToggleAwardEmoji - # Authorize before_action :authorize_read_note! before_action :authorize_create_note!, only: [:create] - before_action :authorize_admin_note!, only: [:update, :destroy] before_action :authorize_resolve_note!, only: [:resolve, :unresolve] - def index - current_fetched_at = Time.now.to_i - - notes_json = { notes: [], last_fetched_at: current_fetched_at } - - @notes = notes_finder.execute.inc_relations_for_view - @notes = prepare_notes_for_rendering(@notes) - - @notes.each do |note| - next if note.cross_reference_not_visible_for?(current_user) - - notes_json[:notes] << note_json(note) - end - - render json: notes_json - end - + # + # This is a fix to make spinach feature tests passing: + # Controller actions are returned from AbstractController::Base and methods of parent classes are + # excluded in order to return only specific controller related methods. + # That is ok for the app (no :create method in ancestors) + # but fails for tests because there is a :create method on FactoryGirl (one of the ancestors) + # + # see https://github.com/rails/rails/blob/v4.2.7/actionpack/lib/abstract_controller/base.rb#L78 + # def create - create_params = note_params.merge( - merge_request_diff_head_sha: params[:merge_request_diff_head_sha], - in_reply_to_discussion_id: params[:in_reply_to_discussion_id] - ) - @note = Notes::CreateService.new(project, current_user, create_params).execute - - if @note.is_a?(Note) - Banzai::NoteRenderer.render([@note], @project, current_user) - end - - respond_to do |format| - format.json { render json: note_json(@note) } - format.html { redirect_back_or_default } - end - end - - def update - @note = Notes::UpdateService.new(project, current_user, note_params).execute(note) - - if @note.is_a?(Note) - Banzai::NoteRenderer.render([@note], @project, current_user) - end - - respond_to do |format| - format.json { render json: note_json(@note) } - format.html { redirect_back_or_default } - end - end - - def destroy - if note.editable? - Notes::DestroyService.new(project, current_user).execute(note) - end - - respond_to do |format| - format.js { head :ok } - end + super end def delete_attachment @@ -110,7 +64,7 @@ class Projects::NotesController < Projects::ApplicationController def note_html(note) render_to_string( - "projects/notes/_note", + "shared/notes/_note", layout: false, formats: [:html], locals: { note: note } @@ -152,76 +106,11 @@ class Projects::NotesController < Projects::ApplicationController ) end - def note_json(note) - attrs = { - commands_changes: note.commands_changes - } - - if note.persisted? - attrs.merge!( - valid: true, - id: note.id, - discussion_id: note.discussion_id(noteable), - html: note_html(note), - note: note.note - ) - - discussion = note.to_discussion(noteable) - unless discussion.individual_note? - attrs.merge!( - discussion_resolvable: discussion.resolvable?, - - diff_discussion_html: diff_discussion_html(discussion), - discussion_html: discussion_html(discussion) - ) - end - else - attrs.merge!( - valid: false, - errors: note.errors - ) - end - - attrs - end - - def authorize_admin_note! - return access_denied! unless can?(current_user, :admin_note, note) + def finder_params + params.merge(last_fetched_at: last_fetched_at) end def authorize_resolve_note! return access_denied! unless can?(current_user, :resolve_note, note) end - - def note_params - params.require(:note).permit( - :project_id, - :noteable_type, - :noteable_id, - :commit_id, - :noteable, - :type, - - :note, - :attachment, - - # LegacyDiffNote - :line_code, - - # DiffNote - :position - ) - end - - def notes_finder - @notes_finder ||= NotesFinder.new(project, current_user, params.merge(last_fetched_at: last_fetched_at)) - end - - def noteable - @noteable ||= notes_finder.target - end - - def last_fetched_at - request.headers['X-Last-Fetched-At'] - end end diff --git a/app/controllers/projects/settings/integrations_controller.rb b/app/controllers/projects/settings/integrations_controller.rb index fb2a4837735..1ff08cce8cb 100644 --- a/app/controllers/projects/settings/integrations_controller.rb +++ b/app/controllers/projects/settings/integrations_controller.rb @@ -5,7 +5,7 @@ module Projects before_action :authorize_admin_project! layout "project_settings" - + def show @hooks = @project.hooks @hook = ProjectHook.new diff --git a/app/controllers/projects/snippets_controller.rb b/app/controllers/projects/snippets_controller.rb index 5c9e0d4d1a1..66f913f8f9d 100644 --- a/app/controllers/projects/snippets_controller.rb +++ b/app/controllers/projects/snippets_controller.rb @@ -3,6 +3,7 @@ class Projects::SnippetsController < Projects::ApplicationController include ToggleAwardEmoji include SpammableActions include SnippetsActions + include RendersBlob before_action :module_enabled before_action :snippet, only: [:show, :edit, :destroy, :update, :raw, :toggle_award_emoji, :mark_as_spam] @@ -55,11 +56,23 @@ class Projects::SnippetsController < Projects::ApplicationController end def show - @note = @project.notes.new(noteable: @snippet) - @noteable = @snippet - - @discussions = @snippet.discussions - @notes = prepare_notes_for_rendering(@discussions.flat_map(&:notes)) + blob = @snippet.blob + override_max_blob_size(blob) + + respond_to do |format| + format.html do + @note = @project.notes.new(noteable: @snippet) + @noteable = @snippet + + @discussions = @snippet.discussions + @notes = prepare_notes_for_rendering(@discussions.flat_map(&:notes)) + render 'show' + end + + format.json do + render_blob_json(blob) + end + end end def destroy diff --git a/app/controllers/snippets/notes_controller.rb b/app/controllers/snippets/notes_controller.rb new file mode 100644 index 00000000000..3c4ddc1680d --- /dev/null +++ b/app/controllers/snippets/notes_controller.rb @@ -0,0 +1,44 @@ +class Snippets::NotesController < ApplicationController + include NotesActions + include ToggleAwardEmoji + + skip_before_action :authenticate_user!, only: [:index] + before_action :snippet + before_action :authorize_read_snippet!, only: [:show, :index, :create] + + private + + def note + @note ||= snippet.notes.find(params[:id]) + end + alias_method :awardable, :note + + def note_html(note) + render_to_string( + "shared/notes/_note", + layout: false, + formats: [:html], + locals: { note: note } + ) + end + + def project + nil + end + + def snippet + PersonalSnippet.find_by(id: params[:snippet_id]) + end + + def note_params + super.merge(noteable_id: params[:snippet_id]) + end + + def finder_params + params.merge(last_fetched_at: last_fetched_at, target_id: snippet.id, target_type: 'personal_snippet') + end + + def authorize_read_snippet! + return render_404 unless can?(current_user, :read_personal_snippet, snippet) + end +end diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb index 056910fad67..da1ae9a34d9 100644 --- a/app/controllers/snippets_controller.rb +++ b/app/controllers/snippets_controller.rb @@ -1,13 +1,15 @@ class SnippetsController < ApplicationController + include RendersNotes include ToggleAwardEmoji include SpammableActions include SnippetsActions include MarkdownPreview + include RendersBlob - before_action :snippet, only: [:show, :edit, :destroy, :update, :raw, :download] + before_action :snippet, only: [:show, :edit, :destroy, :update, :raw] # Allow read snippet - before_action :authorize_read_snippet!, only: [:show, :raw, :download] + before_action :authorize_read_snippet!, only: [:show, :raw] # Allow modify snippet before_action :authorize_update_snippet!, only: [:edit, :update] @@ -15,7 +17,7 @@ class SnippetsController < ApplicationController # Allow destroy snippet before_action :authorize_admin_snippet!, only: [:destroy] - skip_before_action :authenticate_user!, only: [:index, :show, :raw, :download] + skip_before_action :authenticate_user!, only: [:index, :show, :raw] layout 'snippets' respond_to :html @@ -60,6 +62,23 @@ class SnippetsController < ApplicationController end def show + blob = @snippet.blob + override_max_blob_size(blob) + + @noteable = @snippet + + @discussions = @snippet.discussions + @notes = prepare_notes_for_rendering(@discussions.flat_map(&:notes)) + + respond_to do |format| + format.html do + render 'show' + end + + format.json do + render_blob_json(blob) + end + end end def destroy @@ -70,14 +89,6 @@ class SnippetsController < ApplicationController redirect_to snippets_path end - def download - send_data( - convert_line_endings(@snippet.content), - type: 'text/plain; charset=utf-8', - filename: @snippet.sanitized_file_name - ) - end - def preview_markdown render_markdown_preview(params[:text], skip_project_check: true) end |