diff options
-rw-r--r-- | lib/api/api.rb | 3 | ||||
-rw-r--r-- | lib/api/deploy_keys.rb | 84 | ||||
-rw-r--r-- | lib/api/project_hooks.rb | 108 | ||||
-rw-r--r-- | lib/api/project_snippets.rb | 121 | ||||
-rw-r--r-- | lib/api/projects.rb | 261 |
5 files changed, 316 insertions, 261 deletions
diff --git a/lib/api/api.rb b/lib/api/api.rb index 9571d49d9d5..5d97d50cb82 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -36,5 +36,8 @@ module API mount Internal mount SystemHooks mount UserTeams + mount ProjectSnippets + mount DeployKeys + mount ProjectHooks end end diff --git a/lib/api/deploy_keys.rb b/lib/api/deploy_keys.rb new file mode 100644 index 00000000000..55c947eb176 --- /dev/null +++ b/lib/api/deploy_keys.rb @@ -0,0 +1,84 @@ +module API + # Projects API + class DeployKeys < Grape::API + before { authenticate! } + + resource :projects do + helpers do + def handle_project_member_errors(errors) + if errors[:project_access].any? + error!(errors[:project_access], 422) + end + not_found! + end + end + + + # Get a specific project's keys + # + # Example Request: + # GET /projects/:id/keys + get ":id/keys" do + present user_project.deploy_keys, with: Entities::SSHKey + end + + # Get single key owned by currently authenticated user + # + # Example Request: + # GET /projects/:id/keys/:id + get ":id/keys/:key_id" do + key = user_project.deploy_keys.find params[:key_id] + present key, with: Entities::SSHKey + end + + # Add new ssh key to currently authenticated user + # If deploy key already exists - it will be joined to project + # but only if original one was is accessible by same user + # + # Parameters: + # key (required) - New SSH Key + # title (required) - New SSH Key's title + # Example Request: + # POST /projects/:id/keys + post ":id/keys" do + attrs = attributes_for_keys [:title, :key] + + if attrs[:key].present? + attrs[:key].strip! + + # check if key already exist in project + key = user_project.deploy_keys.find_by_key(attrs[:key]) + if key + present key, with: Entities::SSHKey + return + end + + # Check for available deploy keys in other projects + key = current_user.accessible_deploy_keys.find_by_key(attrs[:key]) + if key + user_project.deploy_keys << key + present key, with: Entities::SSHKey + return + end + end + + key = DeployKey.new attrs + + if key.valid? && user_project.deploy_keys << key + present key, with: Entities::SSHKey + else + not_found! + end + end + + # Delete existed ssh key of currently authenticated user + # + # Example Request: + # DELETE /projects/:id/keys/:id + delete ":id/keys/:key_id" do + key = user_project.deploy_keys.find params[:key_id] + key.destroy + end + end + end +end diff --git a/lib/api/project_hooks.rb b/lib/api/project_hooks.rb new file mode 100644 index 00000000000..28501256795 --- /dev/null +++ b/lib/api/project_hooks.rb @@ -0,0 +1,108 @@ +module API + # Projects API + class ProjectHooks < Grape::API + before { authenticate! } + + resource :projects do + helpers do + def handle_project_member_errors(errors) + if errors[:project_access].any? + error!(errors[:project_access], 422) + end + not_found! + end + end + + # Get project hooks + # + # Parameters: + # id (required) - The ID of a project + # Example Request: + # GET /projects/:id/hooks + get ":id/hooks" do + authorize! :admin_project, user_project + @hooks = paginate user_project.hooks + present @hooks, with: Entities::Hook + end + + # Get a project hook + # + # Parameters: + # id (required) - The ID of a project + # hook_id (required) - The ID of a project hook + # Example Request: + # GET /projects/:id/hooks/:hook_id + get ":id/hooks/:hook_id" do + authorize! :admin_project, user_project + @hook = user_project.hooks.find(params[:hook_id]) + present @hook, with: Entities::Hook + end + + + # Add hook to project + # + # Parameters: + # id (required) - The ID of a project + # url (required) - The hook URL + # Example Request: + # POST /projects/:id/hooks + post ":id/hooks" do + authorize! :admin_project, user_project + required_attributes! [:url] + + @hook = user_project.hooks.new({"url" => params[:url]}) + if @hook.save + present @hook, with: Entities::Hook + else + if @hook.errors[:url].present? + error!("Invalid url given", 422) + end + not_found! + end + end + + # Update an existing project hook + # + # Parameters: + # id (required) - The ID of a project + # 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 + required_attributes! [:url] + + attrs = attributes_for_keys [:url] + if @hook.update_attributes attrs + present @hook, with: Entities::Hook + else + if @hook.errors[:url].present? + error!("Invalid url given", 422) + end + not_found! + end + end + + # Deletes project hook. This is an idempotent function. + # + # Parameters: + # id (required) - The ID of a project + # hook_id (required) - The ID of hook to delete + # Example Request: + # DELETE /projects/:id/hooks/:hook_id + delete ":id/hooks/:hook_id" do + authorize! :admin_project, user_project + required_attributes! [:hook_id] + + begin + @hook = ProjectHook.find(params[:hook_id]) + @hook.destroy + rescue + # ProjectHook can raise Error if hook_id not found + end + end + end + end +end diff --git a/lib/api/project_snippets.rb b/lib/api/project_snippets.rb new file mode 100644 index 00000000000..46f70f2dc6b --- /dev/null +++ b/lib/api/project_snippets.rb @@ -0,0 +1,121 @@ +module API + # Projects API + class ProjectSnippets < Grape::API + before { authenticate! } + + resource :projects do + helpers do + def handle_project_member_errors(errors) + if errors[:project_access].any? + error!(errors[:project_access], 422) + end + not_found! + end + end + + # Get a project snippets + # + # Parameters: + # id (required) - The ID of a project + # Example Request: + # GET /projects/:id/snippets + get ":id/snippets" do + present paginate(user_project.snippets), with: Entities::ProjectSnippet + end + + # Get a project snippet + # + # Parameters: + # id (required) - The ID of a project + # snippet_id (required) - The ID of a project snippet + # Example Request: + # GET /projects/:id/snippets/:snippet_id + get ":id/snippets/:snippet_id" do + @snippet = user_project.snippets.find(params[:snippet_id]) + present @snippet, with: Entities::ProjectSnippet + end + + # Create a new project snippet + # + # Parameters: + # id (required) - The ID of a project + # 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 + authorize! :write_project_snippet, user_project + required_attributes! [:title, :file_name, :code] + + attrs = attributes_for_keys [:title, :file_name] + attrs[:expires_at] = params[:lifetime] if params[:lifetime].present? + attrs[:content] = params[:code] if params[:code].present? + @snippet = user_project.snippets.new attrs + @snippet.author = current_user + + if @snippet.save + present @snippet, with: Entities::ProjectSnippet + else + not_found! + end + end + + # Update an existing project snippet + # + # Parameters: + # id (required) - The ID of a project + # 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 + @snippet = user_project.snippets.find(params[:snippet_id]) + authorize! :modify_project_snippet, @snippet + + attrs = attributes_for_keys [:title, :file_name] + attrs[:expires_at] = params[:lifetime] if params[:lifetime].present? + attrs[:content] = params[:code] if params[:code].present? + + if @snippet.update_attributes attrs + present @snippet, with: Entities::ProjectSnippet + else + not_found! + end + end + + # Delete a project snippet + # + # Parameters: + # id (required) - The ID of a project + # snippet_id (required) - The ID of a project snippet + # Example Request: + # DELETE /projects/:id/snippets/:snippet_id + delete ":id/snippets/:snippet_id" do + begin + @snippet = user_project.snippets.find(params[:snippet_id]) + authorize! :modify_project_snippet, @snippet + @snippet.destroy + rescue + end + end + + # Get a raw project snippet + # + # Parameters: + # id (required) - The ID of a project + # 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 + @snippet = user_project.snippets.find(params[:snippet_id]) + content_type 'text/plain' + present @snippet.content + end + end + end +end diff --git a/lib/api/projects.rb b/lib/api/projects.rb index f0648c326d5..7fcde3794f4 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -203,267 +203,6 @@ module API {message: "Access revoked", id: params[:user_id].to_i} end end - - # Get project hooks - # - # Parameters: - # id (required) - The ID of a project - # Example Request: - # GET /projects/:id/hooks - get ":id/hooks" do - authorize! :admin_project, user_project - @hooks = paginate user_project.hooks - present @hooks, with: Entities::Hook - end - - # Get a project hook - # - # Parameters: - # id (required) - The ID of a project - # hook_id (required) - The ID of a project hook - # Example Request: - # GET /projects/:id/hooks/:hook_id - get ":id/hooks/:hook_id" do - authorize! :admin_project, user_project - @hook = user_project.hooks.find(params[:hook_id]) - present @hook, with: Entities::Hook - end - - - # Add hook to project - # - # Parameters: - # id (required) - The ID of a project - # url (required) - The hook URL - # Example Request: - # POST /projects/:id/hooks - post ":id/hooks" do - authorize! :admin_project, user_project - required_attributes! [:url] - - @hook = user_project.hooks.new({"url" => params[:url]}) - if @hook.save - present @hook, with: Entities::Hook - else - if @hook.errors[:url].present? - error!("Invalid url given", 422) - end - not_found! - end - end - - # Update an existing project hook - # - # Parameters: - # id (required) - The ID of a project - # 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 - required_attributes! [:url] - - attrs = attributes_for_keys [:url] - if @hook.update_attributes attrs - present @hook, with: Entities::Hook - else - if @hook.errors[:url].present? - error!("Invalid url given", 422) - end - not_found! - end - end - - # Deletes project hook. This is an idempotent function. - # - # Parameters: - # id (required) - The ID of a project - # hook_id (required) - The ID of hook to delete - # Example Request: - # DELETE /projects/:id/hooks/:hook_id - delete ":id/hooks/:hook_id" do - authorize! :admin_project, user_project - required_attributes! [:hook_id] - - begin - @hook = ProjectHook.find(params[:hook_id]) - @hook.destroy - rescue - # ProjectHook can raise Error if hook_id not found - end - end - - # Get a project snippets - # - # Parameters: - # id (required) - The ID of a project - # Example Request: - # GET /projects/:id/snippets - get ":id/snippets" do - present paginate(user_project.snippets), with: Entities::ProjectSnippet - end - - # Get a project snippet - # - # Parameters: - # id (required) - The ID of a project - # snippet_id (required) - The ID of a project snippet - # Example Request: - # GET /projects/:id/snippets/:snippet_id - get ":id/snippets/:snippet_id" do - @snippet = user_project.snippets.find(params[:snippet_id]) - present @snippet, with: Entities::ProjectSnippet - end - - # Create a new project snippet - # - # Parameters: - # id (required) - The ID of a project - # 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 - authorize! :write_project_snippet, user_project - required_attributes! [:title, :file_name, :code] - - attrs = attributes_for_keys [:title, :file_name] - attrs[:expires_at] = params[:lifetime] if params[:lifetime].present? - attrs[:content] = params[:code] if params[:code].present? - @snippet = user_project.snippets.new attrs - @snippet.author = current_user - - if @snippet.save - present @snippet, with: Entities::ProjectSnippet - else - not_found! - end - end - - # Update an existing project snippet - # - # Parameters: - # id (required) - The ID of a project - # 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 - @snippet = user_project.snippets.find(params[:snippet_id]) - authorize! :modify_project_snippet, @snippet - - attrs = attributes_for_keys [:title, :file_name] - attrs[:expires_at] = params[:lifetime] if params[:lifetime].present? - attrs[:content] = params[:code] if params[:code].present? - - if @snippet.update_attributes attrs - present @snippet, with: Entities::ProjectSnippet - else - not_found! - end - end - - # Delete a project snippet - # - # Parameters: - # id (required) - The ID of a project - # snippet_id (required) - The ID of a project snippet - # Example Request: - # DELETE /projects/:id/snippets/:snippet_id - delete ":id/snippets/:snippet_id" do - begin - @snippet = user_project.snippets.find(params[:snippet_id]) - authorize! :modify_project_snippet, @snippet - @snippet.destroy - rescue - end - end - - # Get a raw project snippet - # - # Parameters: - # id (required) - The ID of a project - # 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 - @snippet = user_project.snippets.find(params[:snippet_id]) - content_type 'text/plain' - present @snippet.content - end - - # Get a specific project's keys - # - # Example Request: - # GET /projects/:id/keys - get ":id/keys" do - present user_project.deploy_keys, with: Entities::SSHKey - end - - # Get single key owned by currently authenticated user - # - # Example Request: - # GET /projects/:id/keys/:id - get ":id/keys/:key_id" do - key = user_project.deploy_keys.find params[:key_id] - present key, with: Entities::SSHKey - end - - # Add new ssh key to currently authenticated user - # If deploy key already exists - it will be joined to project - # but only if original one was owned by same user - # - # Parameters: - # key (required) - New SSH Key - # title (required) - New SSH Key's title - # Example Request: - # POST /projects/:id/keys - post ":id/keys" do - attrs = attributes_for_keys [:title, :key] - - if attrs[:key].present? - attrs[:key].strip! - - # check if key already exist in project - key = user_project.deploy_keys.find_by_key(attrs[:key]) - if key - present key, with: Entities::SSHKey - return - end - - # Check for available deploy keys in other projects - key = current_user.accessible_deploy_keys.find_by_key(attrs[:key]) - if key - user_project.deploy_keys << key - present key, with: Entities::SSHKey - return - end - end - - key = DeployKey.new attrs - - if key.valid? && user_project.deploy_keys << key - present key, with: Entities::SSHKey - else - not_found! - end - end - - # Delete existed ssh key of currently authenticated user - # - # Example Request: - # DELETE /projects/:id/keys/:id - delete ":id/keys/:key_id" do - key = user_project.deploy_keys.find params[:key_id] - key.destroy - end end end end |