summaryrefslogtreecommitdiff
path: root/lib/api/v3/project_snippets.rb
blob: c41fee326100be0076d74cb2aba1d770e77654ea (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
139
140
141
142
module API
  module V3
    class ProjectSnippets < Grape::API
      include PaginationParams

      before { authenticate! }

      params do
        requires :id, type: String, desc: 'The ID of a project'
      end
      resource :projects, requirements: { id: %r{[^/]+} } do
        helpers do
          def handle_project_member_errors(errors)
            if errors[:project_access].any?
              error!(errors[:project_access], 422)
            end
            not_found!
          end

          def snippets_for_current_user
            SnippetsFinder.new(current_user, project: user_project).execute
          end
        end

        desc 'Get all project snippets' do
          success ::API::V3::Entities::ProjectSnippet
        end
        params do
          use :pagination
        end
        get ":id/snippets" do
          present paginate(snippets_for_current_user), with: ::API::V3::Entities::ProjectSnippet
        end

        desc 'Get a single project snippet' do
          success ::API::V3::Entities::ProjectSnippet
        end
        params do
          requires :snippet_id, type: Integer, desc: 'The ID of a project snippet'
        end
        get ":id/snippets/:snippet_id" do
          snippet = snippets_for_current_user.find(params[:snippet_id])
          present snippet, with: ::API::V3::Entities::ProjectSnippet
        end

        desc 'Create a new project snippet' do
          success ::API::V3::Entities::ProjectSnippet
        end
        params do
          requires :title, type: String, desc: 'The title of the snippet'
          requires :file_name, type: String, desc: 'The file name of the snippet'
          requires :code, type: String, desc: 'The content of the snippet'
          requires :visibility_level, type: Integer,
                                      values: [Gitlab::VisibilityLevel::PRIVATE,
                                               Gitlab::VisibilityLevel::INTERNAL,
                                               Gitlab::VisibilityLevel::PUBLIC],
                                      desc: 'The visibility level of the snippet'
        end
        post ":id/snippets" do
          authorize! :create_project_snippet, user_project
          snippet_params = declared_params.merge(request: request, api: true)
          snippet_params[:content] = snippet_params.delete(:code)

          snippet = CreateSnippetService.new(user_project, current_user, snippet_params).execute

          render_spam_error! if snippet.spam?

          if snippet.persisted?
            present snippet, with: ::API::V3::Entities::ProjectSnippet
          else
            render_validation_error!(snippet)
          end
        end

        desc 'Update an existing project snippet' do
          success ::API::V3::Entities::ProjectSnippet
        end
        params do
          requires :snippet_id, type: Integer, desc: 'The ID of a project snippet'
          optional :title, type: String, desc: 'The title of the snippet'
          optional :file_name, type: String, desc: 'The file name of the snippet'
          optional :code, type: String, desc: 'The content of the snippet'
          optional :visibility_level, type: Integer,
                                      values: [Gitlab::VisibilityLevel::PRIVATE,
                                               Gitlab::VisibilityLevel::INTERNAL,
                                               Gitlab::VisibilityLevel::PUBLIC],
                                      desc: 'The visibility level of the snippet'
          at_least_one_of :title, :file_name, :code, :visibility_level
        end
        put ":id/snippets/:snippet_id" do
          snippet = snippets_for_current_user.find_by(id: params.delete(:snippet_id))
          not_found!('Snippet') unless snippet

          authorize! :update_project_snippet, snippet

          snippet_params = declared_params(include_missing: false)
            .merge(request: request, api: true)

          snippet_params[:content] = snippet_params.delete(:code) if snippet_params[:code].present?

          UpdateSnippetService.new(user_project, current_user, snippet,
                                   snippet_params).execute

          render_spam_error! if snippet.spam?

          if snippet.valid?
            present snippet, with: ::API::V3::Entities::ProjectSnippet
          else
            render_validation_error!(snippet)
          end
        end

        desc 'Delete a project snippet'
        params do
          requires :snippet_id, type: Integer, desc: 'The ID of a project snippet'
        end
        delete ":id/snippets/:snippet_id" do
          snippet = snippets_for_current_user.find_by(id: params[:snippet_id])
          not_found!('Snippet') unless snippet

          authorize! :admin_project_snippet, snippet
          snippet.destroy

          status(200)
        end

        desc 'Get a raw project snippet'
        params do
          requires :snippet_id, type: Integer, desc: 'The ID of a project snippet'
        end
        get ":id/snippets/:snippet_id/raw" do
          snippet = snippets_for_current_user.find_by(id: params[:snippet_id])
          not_found!('Snippet') unless snippet

          env['api.format'] = :txt
          content_type 'text/plain'
          present snippet.content
        end
      end
    end
  end
end