summaryrefslogtreecommitdiff
path: root/lib/api/v3/files.rb
blob: 7b4b3448b6d2d77d6817deca58a107fdc432afe7 (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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
module API
  module V3
    class Files < Grape::API
      helpers do
        def commit_params(attrs)
          {
            file_path: attrs[:file_path],
            start_branch: attrs[:branch],
            branch_name: attrs[:branch],
            commit_message: attrs[:commit_message],
            file_content: attrs[:content],
            file_content_encoding: attrs[:encoding],
            author_email: attrs[:author_email],
            author_name: attrs[:author_name]
          }
        end

        def commit_response(attrs)
          {
            file_path: attrs[:file_path],
            branch: attrs[:branch]
          }
        end

        params :simple_file_params do
          requires :file_path, type: String, desc: 'The path to new file. Ex. lib/class.rb'
          requires :branch_name, type: String, desc: 'The name of branch'
          requires :commit_message, type: String, desc: 'Commit Message'
          optional :author_email, type: String, desc: 'The email of the author'
          optional :author_name, type: String, desc: 'The name of the author'
        end

        params :extended_file_params do
          use :simple_file_params
          requires :content, type: String, desc: 'File content'
          optional :encoding, type: String, values: %w[base64], desc: 'File encoding'
        end
      end

      params do
        requires :id, type: String, desc: 'The project ID'
      end
      resource :projects, requirements: { id: %r{[^/]+} } do
        desc 'Get a file from repository'
        params do
          requires :file_path, type: String, desc: 'The path to the file. Ex. lib/class.rb'
          requires :ref, type: String, desc: 'The name of branch, tag, or commit'
        end
        get ":id/repository/files" do
          authorize! :download_code, user_project

          commit = user_project.commit(params[:ref])
          not_found!('Commit') unless commit

          repo = user_project.repository
          blob = repo.blob_at(commit.sha, params[:file_path])
          not_found!('File') unless blob

          blob.load_all_data!
          status(200)

          {
            file_name: blob.name,
            file_path: blob.path,
            size: blob.size,
            encoding: "base64",
            content: Base64.strict_encode64(blob.data),
            ref: params[:ref],
            blob_id: blob.id,
            commit_id: commit.id,
            last_commit_id: repo.last_commit_id_for_path(commit.sha, params[:file_path])
          }
        end

        desc 'Create new file in repository'
        params do
          use :extended_file_params
        end
        post ":id/repository/files" do
          authorize! :push_code, user_project

          file_params = declared_params(include_missing: false)
          file_params[:branch] = file_params.delete(:branch_name)

          result = ::Files::CreateService.new(user_project, current_user, commit_params(file_params)).execute

          if result[:status] == :success
            status(201)
            commit_response(file_params)
          else
            render_api_error!(result[:message], 400)
          end
        end

        desc 'Update existing file in repository'
        params do
          use :extended_file_params
        end
        put ":id/repository/files" do
          authorize! :push_code, user_project

          file_params = declared_params(include_missing: false)
          file_params[:branch] = file_params.delete(:branch_name)

          result = ::Files::UpdateService.new(user_project, current_user, commit_params(file_params)).execute

          if result[:status] == :success
            status(200)
            commit_response(file_params)
          else
            http_status = result[:http_status] || 400
            render_api_error!(result[:message], http_status)
          end
        end

        desc 'Delete an existing file in repository'
        params do
          use :simple_file_params
        end
        delete ":id/repository/files" do
          authorize! :push_code, user_project

          file_params = declared_params(include_missing: false)
          file_params[:branch] = file_params.delete(:branch_name)

          result = ::Files::DeleteService.new(user_project, current_user, commit_params(file_params)).execute

          if result[:status] == :success
            status(200)
            commit_response(file_params)
          else
            render_api_error!(result[:message], 400)
          end
        end
      end
    end
  end
end