projects.rb 13.8 KB
Newer Older
N
Nihad Abbasov 已提交
1 2 3 4 5 6 7 8 9 10 11
module Gitlab
  # Projects API
  class Projects < Grape::API
    before { authenticate! }

    resource :projects do
      # Get a projects list for authenticated user
      #
      # Example Request:
      #   GET /projects
      get do
12
        @projects = paginate current_user.authorized_projects
13
        present @projects, with: Entities::Project
N
Nihad Abbasov 已提交
14 15 16 17 18
      end

      # Get a single project
      #
      # Parameters:
19
      #   id (required) - The ID of a project
N
Nihad Abbasov 已提交
20 21 22
      # Example Request:
      #   GET /projects/:id
      get ":id" do
23
        present user_project, with: Entities::Project
N
Nihad Abbasov 已提交
24 25
      end

26 27 28 29
      # Create new project
      #
      # Parameters:
      #   name (required) - name for new project
30 31 32 33 34 35
      #   description (optional) - short project description
      #   default_branch (optional) - 'master' by default
      #   issues_enabled (optional) - enabled by default
      #   wall_enabled (optional) - enabled by default
      #   merge_requests_enabled (optional) - enabled by default
      #   wiki_enabled (optional) - enabled by default
36 37 38
      # Example Request
      #   POST /projects
      post do
39
        attrs = attributes_for_keys [:name,
40 41 42 43 44
                                    :description,
                                    :default_branch,
                                    :issues_enabled,
                                    :wall_enabled,
                                    :merge_requests_enabled,
A
Alex Denisov 已提交
45
                                    :wiki_enabled]
46
        @project = ::Projects::CreateContext.new(current_user, attrs).execute
47 48 49
        if @project.saved?
          present @project, with: Entities::Project
        else
50
          not_found!
51 52 53
        end
      end

N
Nihad Abbasov 已提交
54
      # Get a project team members
M
miks 已提交
55 56
      #
      # Parameters:
57
      #   id (required) - The ID of a project
V
Valeriy Sizov 已提交
58
      #   query         - Query string
M
miks 已提交
59
      # Example Request:
N
Nihad Abbasov 已提交
60 61
      #   GET /projects/:id/members
      get ":id/members" do
V
Valeriy Sizov 已提交
62 63 64 65 66
        if params[:query].present?
          @members = paginate user_project.users.where("username LIKE ?", "%#{params[:query]}%")
        else
          @members = paginate user_project.users
        end
N
Nihad Abbasov 已提交
67
        present @members, with: Entities::ProjectMember, project: user_project
M
miks 已提交
68 69
      end

N
Nihad Abbasov 已提交
70
      # Get a project team members
71 72
      #
      # Parameters:
73
      #   id (required) - The ID of a project
N
Nihad Abbasov 已提交
74
      #   user_id (required) - The ID of a user
75
      # Example Request:
N
Nihad Abbasov 已提交
76 77 78 79 80 81 82 83 84
      #   GET /projects/:id/members/:user_id
      get ":id/members/:user_id" do
        @member = user_project.users.find params[:user_id]
        present @member, with: Entities::ProjectMember, project: user_project
      end

      # Add a new project team member
      #
      # Parameters:
85
      #   id (required) - The ID of a project
N
Nihad Abbasov 已提交
86 87 88 89 90
      #   user_id (required) - The ID of a user
      #   access_level (required) - Project access level
      # Example Request:
      #   POST /projects/:id/members
      post ":id/members" do
R
randx 已提交
91
        authorize! :admin_project, user_project
N
Nihad Abbasov 已提交
92 93 94 95 96 97 98 99 100 101 102
        users_project = user_project.users_projects.new(
          user_id: params[:user_id],
          project_access: params[:access_level]
        )

        if users_project.save
          @member = users_project.user
          present @member, with: Entities::ProjectMember, project: user_project
        else
          not_found!
        end
103 104
      end

N
Nihad Abbasov 已提交
105
      # Update project team member
M
miks 已提交
106 107
      #
      # Parameters:
108
      #   id (required) - The ID of a project
N
Nihad Abbasov 已提交
109 110
      #   user_id (required) - The ID of a team member
      #   access_level (required) - Project access level
M
miks 已提交
111
      # Example Request:
N
Nihad Abbasov 已提交
112 113
      #   PUT /projects/:id/members/:user_id
      put ":id/members/:user_id" do
R
randx 已提交
114
        authorize! :admin_project, user_project
N
Nihad Abbasov 已提交
115 116 117 118 119 120 121 122
        users_project = user_project.users_projects.find_by_user_id params[:user_id]

        if users_project.update_attributes(project_access: params[:access_level])
          @member = users_project.user
          present @member, with: Entities::ProjectMember, project: user_project
        else
          not_found!
        end
M
miks 已提交
123 124
      end

N
Nihad Abbasov 已提交
125
      # Remove a team member from project
M
miks 已提交
126 127
      #
      # Parameters:
128
      #   id (required) - The ID of a project
N
Nihad Abbasov 已提交
129
      #   user_id (required) - The ID of a team member
M
miks 已提交
130
      # Example Request:
N
Nihad Abbasov 已提交
131 132
      #   DELETE /projects/:id/members/:user_id
      delete ":id/members/:user_id" do
R
randx 已提交
133
        authorize! :admin_project, user_project
N
Nihad Abbasov 已提交
134 135
        users_project = user_project.users_projects.find_by_user_id params[:user_id]
        users_project.destroy
M
miks 已提交
136 137
      end

M
miks 已提交
138 139 140
      # Get project hooks
      #
      # Parameters:
141
      #   id (required) - The ID of a project
M
miks 已提交
142 143 144
      # Example Request:
      #   GET /projects/:id/hooks
      get ":id/hooks" do
M
miks 已提交
145
        authorize! :admin_project, user_project
M
miks 已提交
146 147 148
        @hooks = paginate user_project.hooks
        present @hooks, with: Entities::Hook
      end
S
Saito 已提交
149

J
jozefvaclavik 已提交
150 151 152
      # Get a project hook
      #
      # Parameters:
153
      #   id (required) - The ID of a project
J
jozefvaclavik 已提交
154 155 156 157 158 159 160
      #   hook_id (required) - The ID of a project hook
      # Example Request:
      #   GET /projects/:id/hooks/:hook_id
      get ":id/hooks/:hook_id" do
        @hook = user_project.hooks.find(params[:hook_id])
        present @hook, with: Entities::Hook
      end
S
Saito 已提交
161

M
miks 已提交
162 163 164 165

      # Add hook to project
      #
      # Parameters:
166
      #   id (required) - The ID of a project
M
miks 已提交
167 168 169 170
      #   url (required) - The hook URL
      # Example Request:
      #   POST /projects/:id/hooks
      post ":id/hooks" do
M
miks 已提交
171
        authorize! :admin_project, user_project
M
miks 已提交
172 173 174 175 176 177 178
        @hook = user_project.hooks.new({"url" => params[:url]})
        if @hook.save
          present @hook, with: Entities::Hook
        else
          error!({'message' => '404 Not found'}, 404)
        end
      end
S
Saito 已提交
179

J
jozefvaclavik 已提交
180 181 182
      # Update an existing project hook
      #
      # Parameters:
183
      #   id (required) - The ID of a project
J
jozefvaclavik 已提交
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
      #   hook_id (required) - The ID of a project hook
      #   url (required) - The hook URL
      # Example Request:
      #   PUT /projects/:id/hooks/:hook_id
      put ":id/hooks/:hook_id" do
        @hook = user_project.hooks.find(params[:hook_id])
        authorize! :admin_project, user_project

        attrs = attributes_for_keys [:url]

        if @hook.update_attributes attrs
          present @hook, with: Entities::Hook
        else
          not_found!
        end
      end
M
miks 已提交
200 201 202 203

      # Delete project hook
      #
      # Parameters:
204
      #   id (required) - The ID of a project
M
miks 已提交
205 206 207 208
      #   hook_id (required) - The ID of hook to delete
      # Example Request:
      #   DELETE /projects/:id/hooks
      delete ":id/hooks" do
M
miks 已提交
209
        authorize! :admin_project, user_project
M
miks 已提交
210 211 212 213
        @hook = user_project.hooks.find(params[:hook_id])
        @hook.destroy
      end

N
Nihad Abbasov 已提交
214 215 216
      # Get a project repository branches
      #
      # Parameters:
217
      #   id (required) - The ID of a project
N
Nihad Abbasov 已提交
218 219 220
      # Example Request:
      #   GET /projects/:id/repository/branches
      get ":id/repository/branches" do
221
        present user_project.repo.heads.sort_by(&:name), with: Entities::RepoObject, project: user_project
N
Nihad Abbasov 已提交
222 223
      end

224 225 226
      # Get a single branch
      #
      # Parameters:
227
      #   id (required) - The ID of a project
228
      #   branch (required) - The name of the branch
229
      # Example Request:
230 231 232
      #   GET /projects/:id/repository/branches/:branch
      get ":id/repository/branches/:branch" do
        @branch = user_project.repo.heads.find { |item| item.name == params[:branch] }
233
        error!("Branch does not exist", 404) if @branch.nil?
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
        present @branch, with: Entities::RepoObject, project: user_project
      end

      # Protect a single branch
      #
      # Parameters:
      #   id (required) - The ID of a project
      #   branch (required) - The name of the branch
      # Example Request:
      #   PUT /projects/:id/repository/branches/:branch/protect
      put ":id/repository/branches/:branch/protect" do
        @branch = user_project.repo.heads.find { |item| item.name == params[:branch] }
        protected = user_project.protected_branches.find_by_name(@branch.name)

        unless protected
          user_project.protected_branches.create(:name => @branch.name)
        end

        present @branch, with: Entities::RepoObject, project: user_project
      end

      # Unprotect a single branch
      #
      # Parameters:
      #   id (required) - The ID of a project
      #   branch (required) - The name of the branch
      # Example Request:
      #   PUT /projects/:id/repository/branches/:branch/unprotect
      put ":id/repository/branches/:branch/unprotect" do
        @branch = user_project.repo.heads.find { |item| item.name == params[:branch] }
        protected = user_project.protected_branches.find_by_name(@branch.name)

        if protected
          protected.destroy
        end

        present @branch, with: Entities::RepoObject, project: user_project
271 272
      end

N
Nihad Abbasov 已提交
273 274 275
      # Get a project repository tags
      #
      # Parameters:
276
      #   id (required) - The ID of a project
N
Nihad Abbasov 已提交
277 278 279
      # Example Request:
      #   GET /projects/:id/repository/tags
      get ":id/repository/tags" do
280
        present user_project.repo.tags.sort_by(&:name).reverse, with: Entities::RepoObject
N
Nihad Abbasov 已提交
281
      end
N
Nihad Abbasov 已提交
282

283 284 285
      # Get a project repository commits
      #
      # Parameters:
286
      #   id (required) - The ID of a project
287 288 289 290 291 292 293 294 295 296
      #   ref_name (optional) - The name of a repository branch or tag
      # Example Request:
      #   GET /projects/:id/repository/commits
      get ":id/repository/commits" do
        authorize! :download_code, user_project

        page = params[:page] || 0
        per_page = params[:per_page] || 20
        ref = params[:ref_name] || user_project.try(:default_branch) || 'master'

D
Dmitriy Zaporozhets 已提交
297
        commits = user_project.repository.commits(ref, nil, per_page, page * per_page)
298 299 300
        present CommitDecorator.decorate(commits), with: Entities::RepoCommit
      end

N
Nihad Abbasov 已提交
301 302 303
      # Get a project snippets
      #
      # Parameters:
304
      #   id (required) - The ID of a project
N
Nihad Abbasov 已提交
305 306 307 308 309 310
      # Example Request:
      #   GET /projects/:id/snippets
      get ":id/snippets" do
        present paginate(user_project.snippets), with: Entities::ProjectSnippet
      end

N
Nihad Abbasov 已提交
311 312 313
      # Get a project snippet
      #
      # Parameters:
314
      #   id (required) - The ID of a project
N
Nihad Abbasov 已提交
315 316 317 318
      #   snippet_id (required) - The ID of a project snippet
      # Example Request:
      #   GET /projects/:id/snippets/:snippet_id
      get ":id/snippets/:snippet_id" do
N
Nihad Abbasov 已提交
319
        @snippet = user_project.snippets.find(params[:snippet_id])
320
        present @snippet, with: Entities::ProjectSnippet
N
Nihad Abbasov 已提交
321 322 323 324 325
      end

      # Create a new project snippet
      #
      # Parameters:
326
      #   id (required) - The ID of a project
N
Nihad Abbasov 已提交
327 328 329 330 331 332 333
      #   title (required) - The title of a snippet
      #   file_name (required) - The name of a snippet file
      #   lifetime (optional) - The expiration date of a snippet
      #   code (required) - The content of a snippet
      # Example Request:
      #   POST /projects/:id/snippets
      post ":id/snippets" do
334 335
        authorize! :write_snippet, user_project

A
Alex Denisov 已提交
336
        attrs = attributes_for_keys [:title, :file_name]
A
Alex Denisov 已提交
337 338 339
        attrs[:expires_at] = params[:lifetime] if params[:lifetime].present?
        attrs[:content] = params[:code] if params[:code].present?
        @snippet = user_project.snippets.new attrs
N
Nihad Abbasov 已提交
340 341 342
        @snippet.author = current_user

        if @snippet.save
343
          present @snippet, with: Entities::ProjectSnippet
N
Nihad Abbasov 已提交
344
        else
345
          not_found!
N
Nihad Abbasov 已提交
346 347 348
        end
      end

349 350 351
      # Update an existing project snippet
      #
      # Parameters:
352
      #   id (required) - The ID of a project
353 354 355 356 357 358 359 360
      #   snippet_id (required) - The ID of a project snippet
      #   title (optional) - The title of a snippet
      #   file_name (optional) - The name of a snippet file
      #   lifetime (optional) - The expiration date of a snippet
      #   code (optional) - The content of a snippet
      # Example Request:
      #   PUT /projects/:id/snippets/:snippet_id
      put ":id/snippets/:snippet_id" do
N
Nihad Abbasov 已提交
361
        @snippet = user_project.snippets.find(params[:snippet_id])
R
randx 已提交
362 363
        authorize! :modify_snippet, @snippet

A
Alex Denisov 已提交
364
        attrs = attributes_for_keys [:title, :file_name]
A
Alex Denisov 已提交
365 366
        attrs[:expires_at] = params[:lifetime] if params[:lifetime].present?
        attrs[:content] = params[:code] if params[:code].present?
367

A
Alex Denisov 已提交
368
        if @snippet.update_attributes attrs
369
          present @snippet, with: Entities::ProjectSnippet
370
        else
371
          not_found!
372 373 374
        end
      end

N
Nihad Abbasov 已提交
375 376 377
      # Delete a project snippet
      #
      # Parameters:
378
      #   id (required) - The ID of a project
N
Nihad Abbasov 已提交
379 380 381 382
      #   snippet_id (required) - The ID of a project snippet
      # Example Request:
      #   DELETE /projects/:id/snippets/:snippet_id
      delete ":id/snippets/:snippet_id" do
N
Nihad Abbasov 已提交
383
        @snippet = user_project.snippets.find(params[:snippet_id])
R
randx 已提交
384 385
        authorize! :modify_snippet, @snippet

N
Nihad Abbasov 已提交
386 387
        @snippet.destroy
      end
388 389 390 391

      # Get a raw project snippet
      #
      # Parameters:
392
      #   id (required) - The ID of a project
393 394 395 396
      #   snippet_id (required) - The ID of a project snippet
      # Example Request:
      #   GET /projects/:id/snippets/:snippet_id/raw
      get ":id/snippets/:snippet_id/raw" do
N
Nihad Abbasov 已提交
397
        @snippet = user_project.snippets.find(params[:snippet_id])
398
        content_type 'text/plain'
399 400
        present @snippet.content
      end
401 402 403 404

      # Get a raw file contents
      #
      # Parameters:
405
      #   id (required) - The ID of a project
406
      #   sha (required) - The commit or branch name
407 408 409 410
      #   filepath (required) - The path to the file to display
      # Example Request:
      #   GET /projects/:id/repository/commits/:sha/blob
      get ":id/repository/commits/:sha/blob" do
411 412
        authorize! :download_code, user_project

413 414
        ref = params[:sha]

D
Dmitriy Zaporozhets 已提交
415
        commit = user_project.repository.commit ref
416
        not_found! "Commit" unless commit
417

D
Dmitriy Zaporozhets 已提交
418
        tree = Tree.new commit.tree, ref, params[:filepath]
419
        not_found! "File" unless tree.try(:tree)
420

S
Saito 已提交
421
        content_type tree.mime_type
422 423 424
        present tree.data
      end

N
Nihad Abbasov 已提交
425 426 427
    end
  end
end