summaryrefslogtreecommitdiff
path: root/app/services/wikis/create_attachment_service.rb
blob: 30fe0e371a6c1f48fef5bc7ec6e77b8d9185170f (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
# frozen_string_literal: true

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

    delegate :wiki, to: :project
    delegate :repository, to: :wiki

    def initialize(*args)
      super

      @file_name = truncate_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 truncate_file_name(file_name)
      return unless file_name.present?
      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, project)
        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