diff options
Diffstat (limited to 'app/services')
-rw-r--r-- | app/services/base_service.rb | 7 | ||||
-rw-r--r-- | app/services/boards/issues/list_service.rb | 7 | ||||
-rw-r--r-- | app/services/files/base_service.rb | 11 | ||||
-rw-r--r-- | app/services/files/multi_service.rb | 124 | ||||
-rw-r--r-- | app/services/files/update_service.rb | 6 | ||||
-rw-r--r-- | app/services/members/authorized_destroy_service.rb | 2 | ||||
-rw-r--r-- | app/services/members/destroy_service.rb | 39 | ||||
-rw-r--r-- | app/services/projects/create_service.rb | 20 | ||||
-rw-r--r-- | app/services/projects/fork_service.rb | 2 | ||||
-rw-r--r-- | app/services/system_note_service.rb | 2 |
10 files changed, 193 insertions, 27 deletions
diff --git a/app/services/base_service.rb b/app/services/base_service.rb index 0c208150fb8..1a2bad77a02 100644 --- a/app/services/base_service.rb +++ b/app/services/base_service.rb @@ -56,9 +56,8 @@ class BaseService result end - def success - { - status: :success - } + def success(pass_back = {}) + pass_back[:status] = :success + pass_back end end diff --git a/app/services/boards/issues/list_service.rb b/app/services/boards/issues/list_service.rb index 34efd09ed9f..435a8c6e681 100644 --- a/app/services/boards/issues/list_service.rb +++ b/app/services/boards/issues/list_service.rb @@ -36,12 +36,7 @@ module Boards end def set_state - params[:state] = - case list.list_type.to_sym - when :backlog then 'opened' - when :done then 'closed' - else 'all' - end + params[:state] = list.done? ? 'closed' : 'opened' end def board_label_ids diff --git a/app/services/files/base_service.rb b/app/services/files/base_service.rb index e8465729d06..9bd4bd464f7 100644 --- a/app/services/files/base_service.rb +++ b/app/services/files/base_service.rb @@ -27,8 +27,9 @@ module Files create_target_branch end - if commit - success + result = commit + if result + success(result: result) else error('Something went wrong. Your changes were not committed') end @@ -42,6 +43,12 @@ module Files @source_branch != @target_branch || @source_project != @project end + def file_has_changed? + return false unless @last_commit_sha && last_commit + + @last_commit_sha != last_commit.sha + end + def raise_error(message) raise ValidationError.new(message) end diff --git a/app/services/files/multi_service.rb b/app/services/files/multi_service.rb new file mode 100644 index 00000000000..d28912e1301 --- /dev/null +++ b/app/services/files/multi_service.rb @@ -0,0 +1,124 @@ +require_relative "base_service" + +module Files + class MultiService < Files::BaseService + class FileChangedError < StandardError; end + + def commit + repository.multi_action( + user: current_user, + branch: @target_branch, + message: @commit_message, + actions: params[:actions], + author_email: @author_email, + author_name: @author_name + ) + end + + private + + def validate + super + + params[:actions].each_with_index do |action, index| + unless action[:file_path].present? + raise_error("You must specify a file_path.") + end + + regex_check(action[:file_path]) + regex_check(action[:previous_path]) if action[:previous_path] + + if project.empty_repo? && action[:action] != :create + raise_error("No files to #{action[:action]}.") + end + + validate_file_exists(action) + + case action[:action] + when :create + validate_create(action) + when :update + validate_update(action) + when :delete + validate_delete(action) + when :move + validate_move(action, index) + else + raise_error("Unknown action type `#{action[:action]}`.") + end + end + end + + def validate_file_exists(action) + return if action[:action] == :create + + file_path = action[:file_path] + file_path = action[:previous_path] if action[:action] == :move + + blob = repository.blob_at_branch(params[:branch_name], file_path) + + unless blob + raise_error("File to be #{action[:action]}d `#{file_path}` does not exist.") + end + end + + def last_commit + Gitlab::Git::Commit.last_for_path(repository, @source_branch, @file_path) + end + + def regex_check(file) + if file =~ Gitlab::Regex.directory_traversal_regex + raise_error( + 'Your changes could not be committed, because the file name, `' + + file + + '` ' + + Gitlab::Regex.directory_traversal_regex_message + ) + end + + unless file =~ Gitlab::Regex.file_path_regex + raise_error( + 'Your changes could not be committed, because the file name, `' + + file + + '` ' + + Gitlab::Regex.file_path_regex_message + ) + end + end + + def validate_create(action) + return if project.empty_repo? + + if repository.blob_at_branch(params[:branch_name], action[:file_path]) + raise_error("Your changes could not be committed because a file with the name `#{action[:file_path]}` already exists.") + end + end + + def validate_delete(action) + end + + def validate_move(action, index) + if action[:previous_path].nil? + raise_error("You must supply the original file path when moving file `#{action[:file_path]}`.") + end + + blob = repository.blob_at_branch(params[:branch_name], action[:file_path]) + + if blob + raise_error("Move destination `#{action[:file_path]}` already exists.") + end + + if action[:content].nil? + blob = repository.blob_at_branch(params[:branch_name], action[:previous_path]) + blob.load_all_data!(repository) if blob.truncated? + params[:actions][index][:content] = blob.data + end + end + + def validate_update(action) + if file_has_changed? + raise FileChangedError.new("You are attempting to update a file `#{action[:file_path]}` that has changed since you started editing it.") + end + end + end +end diff --git a/app/services/files/update_service.rb b/app/services/files/update_service.rb index 9e9b5b63f26..c17fdb8d1f1 100644 --- a/app/services/files/update_service.rb +++ b/app/services/files/update_service.rb @@ -23,12 +23,6 @@ module Files end end - def file_has_changed? - return false unless @last_commit_sha && last_commit - - @last_commit_sha != last_commit.sha - end - def last_commit @last_commit ||= Gitlab::Git::Commit. last_for_path(@source_project.repository, @source_branch, @file_path) diff --git a/app/services/members/authorized_destroy_service.rb b/app/services/members/authorized_destroy_service.rb index ca9db59cac7..b7a244c2029 100644 --- a/app/services/members/authorized_destroy_service.rb +++ b/app/services/members/authorized_destroy_service.rb @@ -14,6 +14,8 @@ module Members if member.request? && member.user != user notification_service.decline_access_request(member) end + + member end end end diff --git a/app/services/members/destroy_service.rb b/app/services/members/destroy_service.rb index 9a2bf82ef51..431da8372c9 100644 --- a/app/services/members/destroy_service.rb +++ b/app/services/members/destroy_service.rb @@ -1,17 +1,42 @@ module Members class DestroyService < BaseService - attr_accessor :member, :current_user + include MembersHelper - def initialize(member, current_user) - @member = member + attr_accessor :source + + ALLOWED_SCOPES = %i[members requesters all] + + def initialize(source, current_user, params = {}) + @source = source @current_user = current_user + @params = params end - def execute - unless member && can?(current_user, "destroy_#{member.type.underscore}".to_sym, member) - raise Gitlab::Access::AccessDeniedError - end + def execute(scope = :members) + raise "scope :#{scope} is not allowed!" unless ALLOWED_SCOPES.include?(scope) + + member = find_member!(scope) + + raise Gitlab::Access::AccessDeniedError unless can_destroy_member?(member) + AuthorizedDestroyService.new(member, current_user).execute end + + private + + def find_member!(scope) + condition = params[:user_id] ? { user_id: params[:user_id] } : { id: params[:id] } + case scope + when :all + source.members.find_by(condition) || + source.requesters.find_by!(condition) + else + source.public_send(scope).find_by!(condition) + end + end + + def can_destroy_member?(member) + member && can?(current_user, action_member_permission(:destroy, member), member) + end end end diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb index be749ba4a1c..15d7918e7fd 100644 --- a/app/services/projects/create_service.rb +++ b/app/services/projects/create_service.rb @@ -7,6 +7,8 @@ module Projects def execute forked_from_project_id = params.delete(:forked_from_project_id) import_data = params.delete(:import_data) + @skip_wiki = params.delete(:skip_wiki) + @project = Project.new(params) # Make sure that the user is allowed to use the specified visibility level @@ -15,6 +17,11 @@ module Projects return @project end + unless allowed_fork?(forked_from_project_id) + @project.errors.add(:forked_from_project_id, 'is forbidden') + return @project + end + # Set project name from path if @project.name.present? && @project.path.present? # if both name and path set - everything is ok @@ -71,6 +78,13 @@ module Projects @project.errors.add(:namespace, "is not valid") end + def allowed_fork?(source_project_id) + return true if source_project_id.nil? + + source_project = Project.find_by(id: source_project_id) + current_user.can?(:fork_project, source_project) + end + def allowed_namespace?(user, namespace_id) namespace = Namespace.find_by(id: namespace_id) current_user.can?(:create_projects, namespace) @@ -80,7 +94,7 @@ module Projects log_info("#{@project.owner.name} created a new project \"#{@project.name_with_namespace}\"") unless @project.gitlab_project_import? - @project.create_wiki if @project.feature_available?(:wiki, current_user) + @project.create_wiki unless skip_wiki? @project.build_missing_services @project.create_labels @@ -94,6 +108,10 @@ module Projects end end + def skip_wiki? + !@project.feature_available?(:wiki, current_user) || @skip_wiki + end + def save_project_and_import_data(import_data) Project.transaction do @project.create_or_update_import_data(data: import_data[:data], credentials: import_data[:credentials]) if import_data diff --git a/app/services/projects/fork_service.rb b/app/services/projects/fork_service.rb index a2de4dccece..a2b23ea6171 100644 --- a/app/services/projects/fork_service.rb +++ b/app/services/projects/fork_service.rb @@ -16,6 +16,8 @@ module Projects end new_project = CreateService.new(current_user, new_params).execute + return new_project unless new_project.persisted? + builds_access_level = @project.project_feature.builds_access_level new_project.project_feature.update_attributes(builds_access_level: builds_access_level) diff --git a/app/services/system_note_service.rb b/app/services/system_note_service.rb index bf251816e7e..1ce66d50368 100644 --- a/app/services/system_note_service.rb +++ b/app/services/system_note_service.rb @@ -347,7 +347,7 @@ module SystemNoteService notes = notes.where(noteable_id: noteable.id) end - notes_for_mentioner(mentioner, noteable, notes).count > 0 + notes_for_mentioner(mentioner, noteable, notes).exists? end # Build an Array of lines detailing each commit added in a merge request |