projects.rb 13.9 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,
M
Matt Humphrey 已提交
45
                                    :wiki_enabled,
46
                                    :namespace_id]
47
        @project = ::Projects::CreateContext.new(current_user, attrs).execute
48 49 50
        if @project.saved?
          present @project, with: Entities::Project
        else
51
          not_found!
52 53 54
        end
      end

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

N
Nihad Abbasov 已提交
71
      # Get a project team members
72 73
      #
      # Parameters:
74
      #   id (required) - The ID of a project
N
Nihad Abbasov 已提交
75
      #   user_id (required) - The ID of a user
76
      # Example Request:
N
Nihad Abbasov 已提交
77 78 79 80 81 82 83 84 85
      #   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:
86
      #   id (required) - The ID of a project
N
Nihad Abbasov 已提交
87 88 89 90 91
      #   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 已提交
92
        authorize! :admin_project, user_project
N
Nihad Abbasov 已提交
93 94 95 96 97 98 99 100 101 102 103
        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
104 105
      end

N
Nihad Abbasov 已提交
106
      # Update project team member
M
miks 已提交
107 108
      #
      # Parameters:
109
      #   id (required) - The ID of a project
N
Nihad Abbasov 已提交
110 111
      #   user_id (required) - The ID of a team member
      #   access_level (required) - Project access level
M
miks 已提交
112
      # Example Request:
N
Nihad Abbasov 已提交
113 114
      #   PUT /projects/:id/members/:user_id
      put ":id/members/:user_id" do
R
randx 已提交
115
        authorize! :admin_project, user_project
N
Nihad Abbasov 已提交
116 117 118 119 120 121 122 123
        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 已提交
124 125
      end

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

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

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

M
miks 已提交
164 165 166 167

      # Add hook to project
      #
      # Parameters:
168
      #   id (required) - The ID of a project
M
miks 已提交
169 170 171 172
      #   url (required) - The hook URL
      # Example Request:
      #   POST /projects/:id/hooks
      post ":id/hooks" do
M
miks 已提交
173
        authorize! :admin_project, user_project
M
miks 已提交
174 175 176 177 178 179 180
        @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 已提交
181

J
jozefvaclavik 已提交
182 183 184
      # Update an existing project hook
      #
      # Parameters:
185
      #   id (required) - The ID of a project
J
jozefvaclavik 已提交
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
      #   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 已提交
202 203 204 205

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

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

226 227 228
      # Get a single branch
      #
      # Parameters:
229
      #   id (required) - The ID of a project
230
      #   branch (required) - The name of the branch
231
      # Example Request:
232 233 234
      #   GET /projects/:id/repository/branches/:branch
      get ":id/repository/branches/:branch" do
        @branch = user_project.repo.heads.find { |item| item.name == params[:branch] }
235
        not_found!("Branch does not exist") if @branch.nil?
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 271 272
        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
273 274
      end

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

285 286 287
      # Get a project repository commits
      #
      # Parameters:
288
      #   id (required) - The ID of a project
289 290 291 292 293 294 295
      #   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
N
Nihad Abbasov 已提交
296
        per_page = (params[:per_page] || 20).to_i
297 298
        ref = params[:ref_name] || user_project.try(:default_branch) || 'master'

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

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

N
Nihad Abbasov 已提交
313 314 315
      # Get a project snippet
      #
      # Parameters:
316
      #   id (required) - The ID of a project
N
Nihad Abbasov 已提交
317 318 319 320
      #   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 已提交
321
        @snippet = user_project.snippets.find(params[:snippet_id])
322
        present @snippet, with: Entities::ProjectSnippet
N
Nihad Abbasov 已提交
323 324 325 326 327
      end

      # Create a new project snippet
      #
      # Parameters:
328
      #   id (required) - The ID of a project
N
Nihad Abbasov 已提交
329 330 331 332 333 334 335
      #   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
336 337
        authorize! :write_snippet, user_project

A
Alex Denisov 已提交
338
        attrs = attributes_for_keys [:title, :file_name]
A
Alex Denisov 已提交
339 340 341
        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 已提交
342 343 344
        @snippet.author = current_user

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

351 352 353
      # Update an existing project snippet
      #
      # Parameters:
354
      #   id (required) - The ID of a project
355 356 357 358 359 360 361 362
      #   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 已提交
363
        @snippet = user_project.snippets.find(params[:snippet_id])
R
randx 已提交
364 365
        authorize! :modify_snippet, @snippet

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

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

N
Nihad Abbasov 已提交
377 378 379
      # Delete a project snippet
      #
      # Parameters:
380
      #   id (required) - The ID of a project
N
Nihad Abbasov 已提交
381 382 383 384
      #   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 已提交
385
        @snippet = user_project.snippets.find(params[:snippet_id])
R
randx 已提交
386 387
        authorize! :modify_snippet, @snippet

N
Nihad Abbasov 已提交
388 389
        @snippet.destroy
      end
390 391 392 393

      # Get a raw project snippet
      #
      # Parameters:
394
      #   id (required) - The ID of a project
395 396 397 398
      #   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 已提交
399
        @snippet = user_project.snippets.find(params[:snippet_id])
400
        content_type 'text/plain'
401 402
        present @snippet.content
      end
403 404 405 406

      # Get a raw file contents
      #
      # Parameters:
407
      #   id (required) - The ID of a project
408
      #   sha (required) - The commit or branch name
409 410 411 412
      #   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
413 414
        authorize! :download_code, user_project

415 416
        ref = params[:sha]

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

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

S
Saito 已提交
423
        content_type tree.mime_type
424 425 426
        present tree.data
      end

N
Nihad Abbasov 已提交
427 428 429
    end
  end
end