Commit b05600f28b39b3bf8f469ca7b293117c65217762

Authored by Dmitriy Zaporozhets
1 parent 963f475d

Split Project api on several parts: deploy_keys, hooks, snippets etc

lib/api/api.rb
@@ -36,5 +36,8 @@ module API @@ -36,5 +36,8 @@ module API
36 mount Internal 36 mount Internal
37 mount SystemHooks 37 mount SystemHooks
38 mount UserTeams 38 mount UserTeams
  39 + mount ProjectSnippets
  40 + mount DeployKeys
  41 + mount ProjectHooks
39 end 42 end
40 end 43 end
lib/api/deploy_keys.rb 0 → 100644
@@ -0,0 +1,84 @@ @@ -0,0 +1,84 @@
  1 +module API
  2 + # Projects API
  3 + class DeployKeys < Grape::API
  4 + before { authenticate! }
  5 +
  6 + resource :projects do
  7 + helpers do
  8 + def handle_project_member_errors(errors)
  9 + if errors[:project_access].any?
  10 + error!(errors[:project_access], 422)
  11 + end
  12 + not_found!
  13 + end
  14 + end
  15 +
  16 +
  17 + # Get a specific project's keys
  18 + #
  19 + # Example Request:
  20 + # GET /projects/:id/keys
  21 + get ":id/keys" do
  22 + present user_project.deploy_keys, with: Entities::SSHKey
  23 + end
  24 +
  25 + # Get single key owned by currently authenticated user
  26 + #
  27 + # Example Request:
  28 + # GET /projects/:id/keys/:id
  29 + get ":id/keys/:key_id" do
  30 + key = user_project.deploy_keys.find params[:key_id]
  31 + present key, with: Entities::SSHKey
  32 + end
  33 +
  34 + # Add new ssh key to currently authenticated user
  35 + # If deploy key already exists - it will be joined to project
  36 + # but only if original one was is accessible by same user
  37 + #
  38 + # Parameters:
  39 + # key (required) - New SSH Key
  40 + # title (required) - New SSH Key's title
  41 + # Example Request:
  42 + # POST /projects/:id/keys
  43 + post ":id/keys" do
  44 + attrs = attributes_for_keys [:title, :key]
  45 +
  46 + if attrs[:key].present?
  47 + attrs[:key].strip!
  48 +
  49 + # check if key already exist in project
  50 + key = user_project.deploy_keys.find_by_key(attrs[:key])
  51 + if key
  52 + present key, with: Entities::SSHKey
  53 + return
  54 + end
  55 +
  56 + # Check for available deploy keys in other projects
  57 + key = current_user.accessible_deploy_keys.find_by_key(attrs[:key])
  58 + if key
  59 + user_project.deploy_keys << key
  60 + present key, with: Entities::SSHKey
  61 + return
  62 + end
  63 + end
  64 +
  65 + key = DeployKey.new attrs
  66 +
  67 + if key.valid? && user_project.deploy_keys << key
  68 + present key, with: Entities::SSHKey
  69 + else
  70 + not_found!
  71 + end
  72 + end
  73 +
  74 + # Delete existed ssh key of currently authenticated user
  75 + #
  76 + # Example Request:
  77 + # DELETE /projects/:id/keys/:id
  78 + delete ":id/keys/:key_id" do
  79 + key = user_project.deploy_keys.find params[:key_id]
  80 + key.destroy
  81 + end
  82 + end
  83 + end
  84 +end
lib/api/project_hooks.rb 0 → 100644
@@ -0,0 +1,108 @@ @@ -0,0 +1,108 @@
  1 +module API
  2 + # Projects API
  3 + class ProjectHooks < Grape::API
  4 + before { authenticate! }
  5 +
  6 + resource :projects do
  7 + helpers do
  8 + def handle_project_member_errors(errors)
  9 + if errors[:project_access].any?
  10 + error!(errors[:project_access], 422)
  11 + end
  12 + not_found!
  13 + end
  14 + end
  15 +
  16 + # Get project hooks
  17 + #
  18 + # Parameters:
  19 + # id (required) - The ID of a project
  20 + # Example Request:
  21 + # GET /projects/:id/hooks
  22 + get ":id/hooks" do
  23 + authorize! :admin_project, user_project
  24 + @hooks = paginate user_project.hooks
  25 + present @hooks, with: Entities::Hook
  26 + end
  27 +
  28 + # Get a project hook
  29 + #
  30 + # Parameters:
  31 + # id (required) - The ID of a project
  32 + # hook_id (required) - The ID of a project hook
  33 + # Example Request:
  34 + # GET /projects/:id/hooks/:hook_id
  35 + get ":id/hooks/:hook_id" do
  36 + authorize! :admin_project, user_project
  37 + @hook = user_project.hooks.find(params[:hook_id])
  38 + present @hook, with: Entities::Hook
  39 + end
  40 +
  41 +
  42 + # Add hook to project
  43 + #
  44 + # Parameters:
  45 + # id (required) - The ID of a project
  46 + # url (required) - The hook URL
  47 + # Example Request:
  48 + # POST /projects/:id/hooks
  49 + post ":id/hooks" do
  50 + authorize! :admin_project, user_project
  51 + required_attributes! [:url]
  52 +
  53 + @hook = user_project.hooks.new({"url" => params[:url]})
  54 + if @hook.save
  55 + present @hook, with: Entities::Hook
  56 + else
  57 + if @hook.errors[:url].present?
  58 + error!("Invalid url given", 422)
  59 + end
  60 + not_found!
  61 + end
  62 + end
  63 +
  64 + # Update an existing project hook
  65 + #
  66 + # Parameters:
  67 + # id (required) - The ID of a project
  68 + # hook_id (required) - The ID of a project hook
  69 + # url (required) - The hook URL
  70 + # Example Request:
  71 + # PUT /projects/:id/hooks/:hook_id
  72 + put ":id/hooks/:hook_id" do
  73 + @hook = user_project.hooks.find(params[:hook_id])
  74 + authorize! :admin_project, user_project
  75 + required_attributes! [:url]
  76 +
  77 + attrs = attributes_for_keys [:url]
  78 + if @hook.update_attributes attrs
  79 + present @hook, with: Entities::Hook
  80 + else
  81 + if @hook.errors[:url].present?
  82 + error!("Invalid url given", 422)
  83 + end
  84 + not_found!
  85 + end
  86 + end
  87 +
  88 + # Deletes project hook. This is an idempotent function.
  89 + #
  90 + # Parameters:
  91 + # id (required) - The ID of a project
  92 + # hook_id (required) - The ID of hook to delete
  93 + # Example Request:
  94 + # DELETE /projects/:id/hooks/:hook_id
  95 + delete ":id/hooks/:hook_id" do
  96 + authorize! :admin_project, user_project
  97 + required_attributes! [:hook_id]
  98 +
  99 + begin
  100 + @hook = ProjectHook.find(params[:hook_id])
  101 + @hook.destroy
  102 + rescue
  103 + # ProjectHook can raise Error if hook_id not found
  104 + end
  105 + end
  106 + end
  107 + end
  108 +end
lib/api/project_snippets.rb 0 → 100644
@@ -0,0 +1,121 @@ @@ -0,0 +1,121 @@
  1 +module API
  2 + # Projects API
  3 + class ProjectSnippets < Grape::API
  4 + before { authenticate! }
  5 +
  6 + resource :projects do
  7 + helpers do
  8 + def handle_project_member_errors(errors)
  9 + if errors[:project_access].any?
  10 + error!(errors[:project_access], 422)
  11 + end
  12 + not_found!
  13 + end
  14 + end
  15 +
  16 + # Get a project snippets
  17 + #
  18 + # Parameters:
  19 + # id (required) - The ID of a project
  20 + # Example Request:
  21 + # GET /projects/:id/snippets
  22 + get ":id/snippets" do
  23 + present paginate(user_project.snippets), with: Entities::ProjectSnippet
  24 + end
  25 +
  26 + # Get a project snippet
  27 + #
  28 + # Parameters:
  29 + # id (required) - The ID of a project
  30 + # snippet_id (required) - The ID of a project snippet
  31 + # Example Request:
  32 + # GET /projects/:id/snippets/:snippet_id
  33 + get ":id/snippets/:snippet_id" do
  34 + @snippet = user_project.snippets.find(params[:snippet_id])
  35 + present @snippet, with: Entities::ProjectSnippet
  36 + end
  37 +
  38 + # Create a new project snippet
  39 + #
  40 + # Parameters:
  41 + # id (required) - The ID of a project
  42 + # title (required) - The title of a snippet
  43 + # file_name (required) - The name of a snippet file
  44 + # lifetime (optional) - The expiration date of a snippet
  45 + # code (required) - The content of a snippet
  46 + # Example Request:
  47 + # POST /projects/:id/snippets
  48 + post ":id/snippets" do
  49 + authorize! :write_project_snippet, user_project
  50 + required_attributes! [:title, :file_name, :code]
  51 +
  52 + attrs = attributes_for_keys [:title, :file_name]
  53 + attrs[:expires_at] = params[:lifetime] if params[:lifetime].present?
  54 + attrs[:content] = params[:code] if params[:code].present?
  55 + @snippet = user_project.snippets.new attrs
  56 + @snippet.author = current_user
  57 +
  58 + if @snippet.save
  59 + present @snippet, with: Entities::ProjectSnippet
  60 + else
  61 + not_found!
  62 + end
  63 + end
  64 +
  65 + # Update an existing project snippet
  66 + #
  67 + # Parameters:
  68 + # id (required) - The ID of a project
  69 + # snippet_id (required) - The ID of a project snippet
  70 + # title (optional) - The title of a snippet
  71 + # file_name (optional) - The name of a snippet file
  72 + # lifetime (optional) - The expiration date of a snippet
  73 + # code (optional) - The content of a snippet
  74 + # Example Request:
  75 + # PUT /projects/:id/snippets/:snippet_id
  76 + put ":id/snippets/:snippet_id" do
  77 + @snippet = user_project.snippets.find(params[:snippet_id])
  78 + authorize! :modify_project_snippet, @snippet
  79 +
  80 + attrs = attributes_for_keys [:title, :file_name]
  81 + attrs[:expires_at] = params[:lifetime] if params[:lifetime].present?
  82 + attrs[:content] = params[:code] if params[:code].present?
  83 +
  84 + if @snippet.update_attributes attrs
  85 + present @snippet, with: Entities::ProjectSnippet
  86 + else
  87 + not_found!
  88 + end
  89 + end
  90 +
  91 + # Delete a project snippet
  92 + #
  93 + # Parameters:
  94 + # id (required) - The ID of a project
  95 + # snippet_id (required) - The ID of a project snippet
  96 + # Example Request:
  97 + # DELETE /projects/:id/snippets/:snippet_id
  98 + delete ":id/snippets/:snippet_id" do
  99 + begin
  100 + @snippet = user_project.snippets.find(params[:snippet_id])
  101 + authorize! :modify_project_snippet, @snippet
  102 + @snippet.destroy
  103 + rescue
  104 + end
  105 + end
  106 +
  107 + # Get a raw project snippet
  108 + #
  109 + # Parameters:
  110 + # id (required) - The ID of a project
  111 + # snippet_id (required) - The ID of a project snippet
  112 + # Example Request:
  113 + # GET /projects/:id/snippets/:snippet_id/raw
  114 + get ":id/snippets/:snippet_id/raw" do
  115 + @snippet = user_project.snippets.find(params[:snippet_id])
  116 + content_type 'text/plain'
  117 + present @snippet.content
  118 + end
  119 + end
  120 + end
  121 +end
lib/api/projects.rb
@@ -203,267 +203,6 @@ module API @@ -203,267 +203,6 @@ module API
203 {message: "Access revoked", id: params[:user_id].to_i} 203 {message: "Access revoked", id: params[:user_id].to_i}
204 end 204 end
205 end 205 end
206 -  
207 - # Get project hooks  
208 - #  
209 - # Parameters:  
210 - # id (required) - The ID of a project  
211 - # Example Request:  
212 - # GET /projects/:id/hooks  
213 - get ":id/hooks" do  
214 - authorize! :admin_project, user_project  
215 - @hooks = paginate user_project.hooks  
216 - present @hooks, with: Entities::Hook  
217 - end  
218 -  
219 - # Get a project hook  
220 - #  
221 - # Parameters:  
222 - # id (required) - The ID of a project  
223 - # hook_id (required) - The ID of a project hook  
224 - # Example Request:  
225 - # GET /projects/:id/hooks/:hook_id  
226 - get ":id/hooks/:hook_id" do  
227 - authorize! :admin_project, user_project  
228 - @hook = user_project.hooks.find(params[:hook_id])  
229 - present @hook, with: Entities::Hook  
230 - end  
231 -  
232 -  
233 - # Add hook to project  
234 - #  
235 - # Parameters:  
236 - # id (required) - The ID of a project  
237 - # url (required) - The hook URL  
238 - # Example Request:  
239 - # POST /projects/:id/hooks  
240 - post ":id/hooks" do  
241 - authorize! :admin_project, user_project  
242 - required_attributes! [:url]  
243 -  
244 - @hook = user_project.hooks.new({"url" => params[:url]})  
245 - if @hook.save  
246 - present @hook, with: Entities::Hook  
247 - else  
248 - if @hook.errors[:url].present?  
249 - error!("Invalid url given", 422)  
250 - end  
251 - not_found!  
252 - end  
253 - end  
254 -  
255 - # Update an existing project hook  
256 - #  
257 - # Parameters:  
258 - # id (required) - The ID of a project  
259 - # hook_id (required) - The ID of a project hook  
260 - # url (required) - The hook URL  
261 - # Example Request:  
262 - # PUT /projects/:id/hooks/:hook_id  
263 - put ":id/hooks/:hook_id" do  
264 - @hook = user_project.hooks.find(params[:hook_id])  
265 - authorize! :admin_project, user_project  
266 - required_attributes! [:url]  
267 -  
268 - attrs = attributes_for_keys [:url]  
269 - if @hook.update_attributes attrs  
270 - present @hook, with: Entities::Hook  
271 - else  
272 - if @hook.errors[:url].present?  
273 - error!("Invalid url given", 422)  
274 - end  
275 - not_found!  
276 - end  
277 - end  
278 -  
279 - # Deletes project hook. This is an idempotent function.  
280 - #  
281 - # Parameters:  
282 - # id (required) - The ID of a project  
283 - # hook_id (required) - The ID of hook to delete  
284 - # Example Request:  
285 - # DELETE /projects/:id/hooks/:hook_id  
286 - delete ":id/hooks/:hook_id" do  
287 - authorize! :admin_project, user_project  
288 - required_attributes! [:hook_id]  
289 -  
290 - begin  
291 - @hook = ProjectHook.find(params[:hook_id])  
292 - @hook.destroy  
293 - rescue  
294 - # ProjectHook can raise Error if hook_id not found  
295 - end  
296 - end  
297 -  
298 - # Get a project snippets  
299 - #  
300 - # Parameters:  
301 - # id (required) - The ID of a project  
302 - # Example Request:  
303 - # GET /projects/:id/snippets  
304 - get ":id/snippets" do  
305 - present paginate(user_project.snippets), with: Entities::ProjectSnippet  
306 - end  
307 -  
308 - # Get a project snippet  
309 - #  
310 - # Parameters:  
311 - # id (required) - The ID of a project  
312 - # snippet_id (required) - The ID of a project snippet  
313 - # Example Request:  
314 - # GET /projects/:id/snippets/:snippet_id  
315 - get ":id/snippets/:snippet_id" do  
316 - @snippet = user_project.snippets.find(params[:snippet_id])  
317 - present @snippet, with: Entities::ProjectSnippet  
318 - end  
319 -  
320 - # Create a new project snippet  
321 - #  
322 - # Parameters:  
323 - # id (required) - The ID of a project  
324 - # title (required) - The title of a snippet  
325 - # file_name (required) - The name of a snippet file  
326 - # lifetime (optional) - The expiration date of a snippet  
327 - # code (required) - The content of a snippet  
328 - # Example Request:  
329 - # POST /projects/:id/snippets  
330 - post ":id/snippets" do  
331 - authorize! :write_project_snippet, user_project  
332 - required_attributes! [:title, :file_name, :code]  
333 -  
334 - attrs = attributes_for_keys [:title, :file_name]  
335 - attrs[:expires_at] = params[:lifetime] if params[:lifetime].present?  
336 - attrs[:content] = params[:code] if params[:code].present?  
337 - @snippet = user_project.snippets.new attrs  
338 - @snippet.author = current_user  
339 -  
340 - if @snippet.save  
341 - present @snippet, with: Entities::ProjectSnippet  
342 - else  
343 - not_found!  
344 - end  
345 - end  
346 -  
347 - # Update an existing project snippet  
348 - #  
349 - # Parameters:  
350 - # id (required) - The ID of a project  
351 - # snippet_id (required) - The ID of a project snippet  
352 - # title (optional) - The title of a snippet  
353 - # file_name (optional) - The name of a snippet file  
354 - # lifetime (optional) - The expiration date of a snippet  
355 - # code (optional) - The content of a snippet  
356 - # Example Request:  
357 - # PUT /projects/:id/snippets/:snippet_id  
358 - put ":id/snippets/:snippet_id" do  
359 - @snippet = user_project.snippets.find(params[:snippet_id])  
360 - authorize! :modify_project_snippet, @snippet  
361 -  
362 - attrs = attributes_for_keys [:title, :file_name]  
363 - attrs[:expires_at] = params[:lifetime] if params[:lifetime].present?  
364 - attrs[:content] = params[:code] if params[:code].present?  
365 -  
366 - if @snippet.update_attributes attrs  
367 - present @snippet, with: Entities::ProjectSnippet  
368 - else  
369 - not_found!  
370 - end  
371 - end  
372 -  
373 - # Delete a project snippet  
374 - #  
375 - # Parameters:  
376 - # id (required) - The ID of a project  
377 - # snippet_id (required) - The ID of a project snippet  
378 - # Example Request:  
379 - # DELETE /projects/:id/snippets/:snippet_id  
380 - delete ":id/snippets/:snippet_id" do  
381 - begin  
382 - @snippet = user_project.snippets.find(params[:snippet_id])  
383 - authorize! :modify_project_snippet, @snippet  
384 - @snippet.destroy  
385 - rescue  
386 - end  
387 - end  
388 -  
389 - # Get a raw project snippet  
390 - #  
391 - # Parameters:  
392 - # id (required) - The ID of a project  
393 - # snippet_id (required) - The ID of a project snippet  
394 - # Example Request:  
395 - # GET /projects/:id/snippets/:snippet_id/raw  
396 - get ":id/snippets/:snippet_id/raw" do  
397 - @snippet = user_project.snippets.find(params[:snippet_id])  
398 - content_type 'text/plain'  
399 - present @snippet.content  
400 - end  
401 -  
402 - # Get a specific project's keys  
403 - #  
404 - # Example Request:  
405 - # GET /projects/:id/keys  
406 - get ":id/keys" do  
407 - present user_project.deploy_keys, with: Entities::SSHKey  
408 - end  
409 -  
410 - # Get single key owned by currently authenticated user  
411 - #  
412 - # Example Request:  
413 - # GET /projects/:id/keys/:id  
414 - get ":id/keys/:key_id" do  
415 - key = user_project.deploy_keys.find params[:key_id]  
416 - present key, with: Entities::SSHKey  
417 - end  
418 -  
419 - # Add new ssh key to currently authenticated user  
420 - # If deploy key already exists - it will be joined to project  
421 - # but only if original one was owned by same user  
422 - #  
423 - # Parameters:  
424 - # key (required) - New SSH Key  
425 - # title (required) - New SSH Key's title  
426 - # Example Request:  
427 - # POST /projects/:id/keys  
428 - post ":id/keys" do  
429 - attrs = attributes_for_keys [:title, :key]  
430 -  
431 - if attrs[:key].present?  
432 - attrs[:key].strip!  
433 -  
434 - # check if key already exist in project  
435 - key = user_project.deploy_keys.find_by_key(attrs[:key])  
436 - if key  
437 - present key, with: Entities::SSHKey  
438 - return  
439 - end  
440 -  
441 - # Check for available deploy keys in other projects  
442 - key = current_user.accessible_deploy_keys.find_by_key(attrs[:key])  
443 - if key  
444 - user_project.deploy_keys << key  
445 - present key, with: Entities::SSHKey  
446 - return  
447 - end  
448 - end  
449 -  
450 - key = DeployKey.new attrs  
451 -  
452 - if key.valid? && user_project.deploy_keys << key  
453 - present key, with: Entities::SSHKey  
454 - else  
455 - not_found!  
456 - end  
457 - end  
458 -  
459 - # Delete existed ssh key of currently authenticated user  
460 - #  
461 - # Example Request:  
462 - # DELETE /projects/:id/keys/:id  
463 - delete ":id/keys/:key_id" do  
464 - key = user_project.deploy_keys.find params[:key_id]  
465 - key.destroy  
466 - end  
467 end 206 end
468 end 207 end
469 end 208 end