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
      #   hook_id (required) - The ID of a project hook
      # Example Request:
      #   GET /projects/:id/hooks/:hook_id
      get ":id/hooks/:hook_id" do
158
        authorize! :admin_project, user_project
J
jozefvaclavik 已提交
159 160 161
        @hook = user_project.hooks.find(params[:hook_id])
        present @hook, with: Entities::Hook
      end
S
Saito 已提交
162

M
miks 已提交
163 164 165 166

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

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

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

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

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

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

284 285 286
      # Get a project repository commits
      #
      # Parameters:
287
      #   id (required) - The ID of a project
288 289 290 291 292 293 294 295 296 297
      #   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 已提交
298
        commits = user_project.repository.commits(ref, nil, per_page, page * per_page)
299 300 301
        present CommitDecorator.decorate(commits), with: Entities::RepoCommit
      end

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

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

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

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

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

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

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

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

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

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

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

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

414 415
        ref = params[:sha]

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

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

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

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