Welcome to mirror list, hosted at ThFree Co, Russian Federation.

create_attachment_service.rb « wikis « services « app - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 82179459345bbd7a753725ba44de9aebfc02d8ed (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# frozen_string_literal: true

module Wikis
  class CreateAttachmentService < Files::CreateService
    ATTACHMENT_PATH = 'uploads'
    MAX_FILENAME_LENGTH = 255

    attr_reader :container

    delegate :wiki, to: :container
    delegate :repository, to: :wiki

    def initialize(container:, current_user: nil, params: {})
      super(nil, current_user, params)

      @container = container
      @file_name = clean_file_name(params[:file_name])
      @file_path = File.join(ATTACHMENT_PATH, SecureRandom.hex, @file_name) if @file_name
      @commit_message ||= "Upload attachment #{@file_name}"
      @branch_name ||= wiki.default_branch
    end

    def create_commit!
      commit_result(create_transformed_commit(@file_content))
    end

    private

    def clean_file_name(file_name)
      return unless file_name.present?

      file_name = truncate_file_name(file_name)
      # CommonMark does not allow Urls with whitespaces, so we have to replace them
      # Using the same regex Carrierwave use to replace invalid characters
      file_name.gsub(CarrierWave::SanitizedFile.sanitize_regexp, '_')
    end

    def truncate_file_name(file_name)
      return file_name if file_name.length <= MAX_FILENAME_LENGTH

      extension = File.extname(file_name)
      truncate_at = MAX_FILENAME_LENGTH - extension.length - 1
      base_name = File.basename(file_name, extension)[0..truncate_at]
      base_name + extension
    end

    def validate!
      validate_file_name!
      validate_permissions!
    end

    def validate_file_name!
      raise_error('The file name cannot be empty') unless @file_name
    end

    def validate_permissions!
      unless can?(current_user, :create_wiki, container)
        raise_error('You are not allowed to push to the wiki')
      end
    end

    def create_transformed_commit(content)
      repository.create_file(
        current_user,
        @file_path,
        content,
        message: @commit_message,
        branch_name: @branch_name,
        author_email: @author_email,
        author_name: @author_name)
    end

    def commit_result(commit_id)
      {
        file_name: @file_name,
        file_path: @file_path,
        branch: @branch_name,
        commit: commit_id
      }
    end
  end
end