Commit 6413bfb5c640d44d38fe4054c7b33f1db285c687
Exists in
master
and in
4 other branches
Merge branch 'master' into full-post-to-oss-security
Conflicts: doc/release/security.md
Showing
25 changed files
with
344 additions
and
29 deletions
Show diff stats
CHANGELOG
@@ -9,6 +9,7 @@ v 6.3.0 | @@ -9,6 +9,7 @@ v 6.3.0 | ||
9 | - Fixed issue with 500 error when group did not exist | 9 | - Fixed issue with 500 error when group did not exist |
10 | - Ability to leave project | 10 | - Ability to leave project |
11 | - You can create file in repo using UI | 11 | - You can create file in repo using UI |
12 | + - You can remove file from repo using UI | ||
12 | - API: dropped default_branch attribute from project during creation | 13 | - API: dropped default_branch attribute from project during creation |
13 | - Project default_branch is not stored in db any more. It takes from repo now. | 14 | - Project default_branch is not stored in db any more. It takes from repo now. |
14 | - Admin broadcast messages | 15 | - Admin broadcast messages |
@@ -16,8 +17,26 @@ v 6.3.0 | @@ -16,8 +17,26 @@ v 6.3.0 | ||
16 | - Dont show last push widget if user removed this branch | 17 | - Dont show last push widget if user removed this branch |
17 | - Fix 500 error for repos with newline in file name | 18 | - Fix 500 error for repos with newline in file name |
18 | - Extended html titles | 19 | - Extended html titles |
19 | - - API: create/update repo files | 20 | + - API: create/update/delete repo files |
20 | - Admin can transfer project to any namespace | 21 | - Admin can transfer project to any namespace |
22 | + - API: projects/all for admin users | ||
23 | + - Fix recent branches order | ||
24 | + | ||
25 | +v 6.2.4 | ||
26 | + - Security: Cast API private_token to string (CVE-2013-4580) | ||
27 | + - Security: Require gitlab-shell 1.7.8 (CVE-2013-4581, CVE-2013-4582, CVE-2013-4583) | ||
28 | + - Fix for Git SSH access for LDAP users | ||
29 | + | ||
30 | +v 6.2.3 | ||
31 | + - Security: More protection against CVE-2013-4489 | ||
32 | + - Security: Require gitlab-shell 1.7.4 (CVE-2013-4490, CVE-2013-4546) | ||
33 | + - Fix sidekiq rake tasks | ||
34 | + | ||
35 | +v 6.2.2 | ||
36 | + - Security: Update gitlab_git (CVE-2013-4489) | ||
37 | + | ||
38 | +v 6.2.1 | ||
39 | + - Security: Fix issue with generated passwords for new users | ||
21 | 40 | ||
22 | v 6.2.0 | 41 | v 6.2.0 |
23 | - Public project pages are now visible to everyone (files, issues, wik, etc.) | 42 | - Public project pages are now visible to everyone (files, issues, wik, etc.) |
@@ -104,6 +123,14 @@ v 6.0.0 | @@ -104,6 +123,14 @@ v 6.0.0 | ||
104 | - Improved MR comments logic | 123 | - Improved MR comments logic |
105 | - Render readme file for projects in public area | 124 | - Render readme file for projects in public area |
106 | 125 | ||
126 | +v 5.4.2 | ||
127 | + - Security: Cast API private_token to string (CVE-2013-4580) | ||
128 | + - Security: Require gitlab-shell 1.7.8 (CVE-2013-4581, CVE-2013-4582, CVE-2013-4583) | ||
129 | + | ||
130 | +v 5.4.1 | ||
131 | + - Security: Fixes for CVE-2013-4489 | ||
132 | + - Security: Require gitlab-shell 1.7.4 (CVE-2013-4490, CVE-2013-4546) | ||
133 | + | ||
107 | v 5.4.0 | 134 | v 5.4.0 |
108 | - Ability to edit own comments | 135 | - Ability to edit own comments |
109 | - Documentation improvements | 136 | - Documentation improvements |
VERSION
app/assets/stylesheets/gitlab_bootstrap/common.scss
@@ -93,6 +93,12 @@ pre.well-pre { | @@ -93,6 +93,12 @@ pre.well-pre { | ||
93 | font-size: 12px; | 93 | font-size: 12px; |
94 | font-style: normal; | 94 | font-style: normal; |
95 | font-weight: normal; | 95 | font-weight: normal; |
96 | + | ||
97 | + &.label-gray { | ||
98 | + background-color: #eee; | ||
99 | + color: #999; | ||
100 | + text-shadow: none; | ||
101 | + } | ||
96 | } | 102 | } |
97 | 103 | ||
98 | /** Big Labels **/ | 104 | /** Big Labels **/ |
app/assets/stylesheets/gitlab_bootstrap/forms.scss
@@ -3,6 +3,16 @@ form { | @@ -3,6 +3,16 @@ form { | ||
3 | 3 | ||
4 | label { | 4 | label { |
5 | @extend .control-label; | 5 | @extend .control-label; |
6 | + | ||
7 | + &.radio-label { | ||
8 | + text-align: left; | ||
9 | + width: 100%; | ||
10 | + margin-left: 0; | ||
11 | + | ||
12 | + input[type="radio"] { | ||
13 | + margin-top: 1px !important; | ||
14 | + } | ||
15 | + } | ||
6 | } | 16 | } |
7 | } | 17 | } |
8 | 18 |
@@ -0,0 +1,38 @@ | @@ -0,0 +1,38 @@ | ||
1 | +module Files | ||
2 | + class DeleteContext < BaseContext | ||
3 | + def execute | ||
4 | + allowed = if project.protected_branch?(ref) | ||
5 | + can?(current_user, :push_code_to_protected_branches, project) | ||
6 | + else | ||
7 | + can?(current_user, :push_code, project) | ||
8 | + end | ||
9 | + | ||
10 | + unless allowed | ||
11 | + return error("You are not allowed to push into this branch") | ||
12 | + end | ||
13 | + | ||
14 | + unless repository.branch_names.include?(ref) | ||
15 | + return error("You can only create files if you are on top of a branch") | ||
16 | + end | ||
17 | + | ||
18 | + blob = repository.blob_at(ref, path) | ||
19 | + | ||
20 | + unless blob | ||
21 | + return error("You can only edit text files") | ||
22 | + end | ||
23 | + | ||
24 | + delete_file_action = Gitlab::Satellite::DeleteFileAction.new(current_user, project, ref, path) | ||
25 | + | ||
26 | + deleted_successfully = delete_file_action.commit!( | ||
27 | + nil, | ||
28 | + params[:commit_message] | ||
29 | + ) | ||
30 | + | ||
31 | + if deleted_successfully | ||
32 | + success | ||
33 | + else | ||
34 | + error("Your changes could not be commited, because the file has been changed") | ||
35 | + end | ||
36 | + end | ||
37 | + end | ||
38 | +end |
app/controllers/projects/blob_controller.rb
@@ -7,9 +7,30 @@ class Projects::BlobController < Projects::ApplicationController | @@ -7,9 +7,30 @@ class Projects::BlobController < Projects::ApplicationController | ||
7 | before_filter :authorize_code_access! | 7 | before_filter :authorize_code_access! |
8 | before_filter :require_non_empty_project | 8 | before_filter :require_non_empty_project |
9 | 9 | ||
10 | + before_filter :blob | ||
11 | + | ||
10 | def show | 12 | def show |
11 | - @blob = @repository.blob_at(@commit.id, @path) | 13 | + end |
14 | + | ||
15 | + def destroy | ||
16 | + result = Files::DeleteContext.new(@project, current_user, params, @ref, @path).execute | ||
17 | + | ||
18 | + if result[:status] == :success | ||
19 | + flash[:notice] = "Your changes have been successfully commited" | ||
20 | + redirect_to project_tree_path(@project, @ref) | ||
21 | + else | ||
22 | + flash[:alert] = result[:error] | ||
23 | + render :show | ||
24 | + end | ||
25 | + end | ||
26 | + | ||
27 | + private | ||
28 | + | ||
29 | + def blob | ||
30 | + @blob ||= @repository.blob_at(@commit.id, @path) | ||
31 | + | ||
32 | + return not_found! unless @blob | ||
12 | 33 | ||
13 | - not_found! unless @blob | 34 | + @blob |
14 | end | 35 | end |
15 | end | 36 | end |
app/views/projects/blob/_actions.html.haml
@@ -4,7 +4,7 @@ | @@ -4,7 +4,7 @@ | ||
4 | - if allowed_tree_edit? | 4 | - if allowed_tree_edit? |
5 | = link_to "edit", project_edit_tree_path(@project, @id), class: "btn btn-small" | 5 | = link_to "edit", project_edit_tree_path(@project, @id), class: "btn btn-small" |
6 | - else | 6 | - else |
7 | - %span.btn.btn-small.disabled Edit | 7 | + %span.btn.btn-small.disabled edit |
8 | = link_to "raw", project_raw_path(@project, @id), class: "btn btn-small", target: "_blank" | 8 | = link_to "raw", project_raw_path(@project, @id), class: "btn btn-small", target: "_blank" |
9 | -# only show normal/blame view links for text files | 9 | -# only show normal/blame view links for text files |
10 | - if @blob.text? | 10 | - if @blob.text? |
@@ -13,3 +13,7 @@ | @@ -13,3 +13,7 @@ | ||
13 | - else | 13 | - else |
14 | = link_to "blame", project_blame_path(@project, @id), class: "btn btn-small" unless @blob.empty? | 14 | = link_to "blame", project_blame_path(@project, @id), class: "btn btn-small" unless @blob.empty? |
15 | = link_to "history", project_commits_path(@project, @id), class: "btn btn-small" | 15 | = link_to "history", project_commits_path(@project, @id), class: "btn btn-small" |
16 | + | ||
17 | + - if allowed_tree_edit? | ||
18 | + = link_to '#modal-remove-blob', class: "remove-blob btn btn-small btn-remove", "data-toggle" => "modal" do | ||
19 | + remove |
@@ -0,0 +1,19 @@ | @@ -0,0 +1,19 @@ | ||
1 | +%div#modal-remove-blob.modal.hide | ||
2 | + .modal-header | ||
3 | + %a.close{href: "#", "data-dismiss" => "modal"} × | ||
4 | + %h3.page-title Remove #{@blob.name} | ||
5 | + %p.light | ||
6 | + From branch | ||
7 | + %strong= @ref | ||
8 | + | ||
9 | + .modal-body | ||
10 | + = form_tag project_blob_path(@project, @id), method: :delete do | ||
11 | + .control-group.commit_message-group | ||
12 | + = label_tag 'commit_message', class: "control-label" do | ||
13 | + Commit message | ||
14 | + .controls | ||
15 | + = text_area_tag 'commit_message', params[:commit_message], placeholder: "Removed this file because...", required: true, rows: 3 | ||
16 | + .control-group | ||
17 | + .controls | ||
18 | + = submit_tag 'Remove file', class: 'btn btn-remove' | ||
19 | + = link_to "Cancel", '#', class: "btn btn-cancel", "data-dismiss" => "modal" |
app/views/projects/blob/show.html.haml
@@ -2,3 +2,6 @@ | @@ -2,3 +2,6 @@ | ||
2 | = render 'shared/ref_switcher', destination: 'blob', path: @path | 2 | = render 'shared/ref_switcher', destination: 'blob', path: @path |
3 | %div#tree-holder.tree-holder | 3 | %div#tree-holder.tree-holder |
4 | = render 'blob', blob: @blob | 4 | = render 'blob', blob: @blob |
5 | + | ||
6 | +- if allowed_tree_edit? | ||
7 | + = render 'projects/blob/remove' |
app/views/snippets/_form.html.haml
@@ -13,9 +13,20 @@ | @@ -13,9 +13,20 @@ | ||
13 | = f.label :title | 13 | = f.label :title |
14 | .controls= f.text_field :title, placeholder: "Example Snippet", class: 'input-xlarge', required: true | 14 | .controls= f.text_field :title, placeholder: "Example Snippet", class: 'input-xlarge', required: true |
15 | .control-group | 15 | .control-group |
16 | - = f.label "Private?" | 16 | + = f.label "Access" |
17 | .controls | 17 | .controls |
18 | - = f.check_box :private, {class: ''} | 18 | + = f.label :private_true, class: 'radio-label' do |
19 | + = f.radio_button :private, true | ||
20 | + %span | ||
21 | + %strong Private | ||
22 | + (only you can see this snippet) | ||
23 | + %br | ||
24 | + = f.label :private_false, class: 'radio-label' do | ||
25 | + = f.radio_button :private, false | ||
26 | + %span | ||
27 | + %strong Public | ||
28 | + (GitLab users can can see this snippet) | ||
29 | + | ||
19 | .control-group | 30 | .control-group |
20 | .file-editor | 31 | .file-editor |
21 | = f.label :file_name, "File" | 32 | = f.label :file_name, "File" |
@@ -33,9 +44,10 @@ | @@ -33,9 +44,10 @@ | ||
33 | - else | 44 | - else |
34 | = f.submit 'Save', class: "btn-save btn" | 45 | = f.submit 'Save', class: "btn-save btn" |
35 | 46 | ||
36 | - = link_to "Cancel", snippets_path(@project), class: "btn btn-cancel" | ||
37 | - unless @snippet.new_record? | 47 | - unless @snippet.new_record? |
38 | - .pull-right= link_to 'Destroy', snippet_path(@snippet), confirm: 'Removed snippet cannot be restored! Are you sure?', method: :delete, class: "btn pull-right danger delete-snippet", id: "destroy_snippet_#{@snippet.id}" | 48 | + .pull-right.prepend-left-20 |
49 | + = link_to 'Remove', snippet_path(@snippet), confirm: 'Removed snippet cannot be restored! Are you sure?', method: :delete, class: "btn btn-remove delete-snippet", id: "destroy_snippet_#{@snippet.id}" | ||
50 | + = link_to "Cancel", snippets_path(@project), class: "btn btn-cancel" | ||
39 | 51 | ||
40 | 52 | ||
41 | :javascript | 53 | :javascript |
app/views/snippets/_snippet.html.haml
@@ -3,7 +3,7 @@ | @@ -3,7 +3,7 @@ | ||
3 | = link_to reliable_snippet_path(snippet) do | 3 | = link_to reliable_snippet_path(snippet) do |
4 | = truncate(snippet.title, length: 60) | 4 | = truncate(snippet.title, length: 60) |
5 | - if snippet.private? | 5 | - if snippet.private? |
6 | - %span.label.label-success | 6 | + %span.label.label-gray |
7 | %i.icon-lock | 7 | %i.icon-lock |
8 | private | 8 | private |
9 | %span.cgray.monospace.tiny.pull-right | 9 | %span.cgray.monospace.tiny.pull-right |
config/routes.rb
@@ -173,7 +173,7 @@ Gitlab::Application.routes.draw do | @@ -173,7 +173,7 @@ Gitlab::Application.routes.draw do | ||
173 | end | 173 | end |
174 | 174 | ||
175 | scope module: :projects do | 175 | scope module: :projects do |
176 | - resources :blob, only: [:show], constraints: {id: /.+/} | 176 | + resources :blob, only: [:show, :destroy], constraints: {id: /.+/} |
177 | resources :raw, only: [:show], constraints: {id: /.+/} | 177 | resources :raw, only: [:show], constraints: {id: /.+/} |
178 | resources :tree, only: [:show], constraints: {id: /.+/, format: /(html|js)/ } | 178 | resources :tree, only: [:show], constraints: {id: /.+/, format: /(html|js)/ } |
179 | resources :edit_tree, only: [:show, :update], constraints: {id: /.+/}, path: 'edit' | 179 | resources :edit_tree, only: [:show, :update], constraints: {id: /.+/}, path: 'edit' |
doc/api/projects.md
@@ -2,7 +2,7 @@ | @@ -2,7 +2,7 @@ | ||
2 | 2 | ||
3 | ### List projects | 3 | ### List projects |
4 | 4 | ||
5 | -Get a list of projects owned by the authenticated user. | 5 | +Get a list of projects accessible by the authenticated user. |
6 | 6 | ||
7 | ``` | 7 | ``` |
8 | GET /projects | 8 | GET /projects |
@@ -82,6 +82,22 @@ GET /projects | @@ -82,6 +82,22 @@ GET /projects | ||
82 | ``` | 82 | ``` |
83 | 83 | ||
84 | 84 | ||
85 | +#### List owned projects | ||
86 | + | ||
87 | +Get a list of projects owned by the authenticated user. | ||
88 | + | ||
89 | +``` | ||
90 | +GET /projects/owned | ||
91 | +``` | ||
92 | + | ||
93 | +#### List ALL projects | ||
94 | + | ||
95 | +Get a list of all GitLab projects (admin only). | ||
96 | + | ||
97 | +``` | ||
98 | +GET /projects/all | ||
99 | +``` | ||
100 | + | ||
85 | ### Get single project | 101 | ### Get single project |
86 | 102 | ||
87 | Get a specific project, identified by project ID or NAMESPACE/PROJECT_NAME , which is owned by the authentication user. | 103 | Get a specific project, identified by project ID or NAMESPACE/PROJECT_NAME , which is owned by the authentication user. |
doc/api/repositories.md
@@ -397,3 +397,15 @@ Parameters: | @@ -397,3 +397,15 @@ Parameters: | ||
397 | + `branch_name` (required) - The name of branch | 397 | + `branch_name` (required) - The name of branch |
398 | + `content` (required) - New file content | 398 | + `content` (required) - New file content |
399 | + `commit_message` (required) - Commit message | 399 | + `commit_message` (required) - Commit message |
400 | + | ||
401 | +## Delete existing file in repository | ||
402 | + | ||
403 | +``` | ||
404 | +DELETE /projects/:id/repository/files | ||
405 | +``` | ||
406 | + | ||
407 | +Parameters: | ||
408 | + | ||
409 | ++ `file_path` (required) - Full path to file. Ex. lib/class.rb | ||
410 | ++ `branch_name` (required) - The name of branch | ||
411 | ++ `commit_message` (required) - Commit message |
doc/release/security.md
@@ -13,12 +13,14 @@ Please report suspected security vulnerabilities in private to support@gitlab.co | @@ -13,12 +13,14 @@ Please report suspected security vulnerabilities in private to support@gitlab.co | ||
13 | 13 | ||
14 | 1. Verify that the issue can be repoduced | 14 | 1. Verify that the issue can be repoduced |
15 | 1. Acknowledge the issue to the researcher that disclosed it | 15 | 1. Acknowledge the issue to the researcher that disclosed it |
16 | -1. Fix the issue on a feature branch, do this on the private dev.gitlab.org server and update the VERSION and CHANGELOG | 16 | +1. Fix the issue on a feature branch, do this on the private GitLab development server and update the VERSION and CHANGELOG in this branch |
17 | 1. Consider creating and testing workarounds | 17 | 1. Consider creating and testing workarounds |
18 | 1. Create feature branches for the blog posts on GitLab.org and GitLab.com and link them from the code branch | 18 | 1. Create feature branches for the blog posts on GitLab.org and GitLab.com and link them from the code branch |
19 | -1. Merge the code feature branch | ||
20 | -1. Create a git tag vX.X.X for CE and another one for EE | 19 | +1. Merge the code feature branch into master |
20 | +1. Cherry-pick the code into the latest stable branch | ||
21 | +1. Create a git tag vX.X.X for CE and another patch release for EE | ||
21 | 1. Push the code and the tags to all the CE and EE repositories | 22 | 1. Push the code and the tags to all the CE and EE repositories |
23 | +1. Apply the patch to GitLab Cloud and the private GitLab development server | ||
22 | 1. Merge and publish the blog posts | 24 | 1. Merge and publish the blog posts |
23 | 1. Send tweets about the release from @gitlabhq and @git_lab | 25 | 1. Send tweets about the release from @gitlabhq and @git_lab |
24 | 1. Send out an email to the subscribers mailing list on MailChimp | 26 | 1. Send out an email to the subscribers mailing list on MailChimp |
@@ -27,13 +29,17 @@ Please report suspected security vulnerabilities in private to support@gitlab.co | @@ -27,13 +29,17 @@ Please report suspected security vulnerabilities in private to support@gitlab.co | ||
27 | 1. Post a signed copy of our complete announcement to [oss-security](http://www.openwall.com/lists/oss-security/) and request a CVE number | 29 | 1. Post a signed copy of our complete announcement to [oss-security](http://www.openwall.com/lists/oss-security/) and request a CVE number |
28 | 1. Add the security researcher to the [Security Researcher Acknowledgments list](http://www.gitlab.com/vulnerability-acknowledgements/) | 30 | 1. Add the security researcher to the [Security Researcher Acknowledgments list](http://www.gitlab.com/vulnerability-acknowledgements/) |
29 | 1. Thank the security researcher in an email for their cooperation | 31 | 1. Thank the security researcher in an email for their cooperation |
30 | -1. Update the blogposts and the CHANGELOG when we receive a CVE number | 32 | +1. Update the blogpost and the CHANGELOG when we receive the CVE number |
33 | + | ||
34 | +The timing of the code merge into master should be coordinated in advance. | ||
35 | +After the merge we strive to publish the announcements within 60 minutes. | ||
31 | 36 | ||
32 | ## Blog post template | 37 | ## Blog post template |
33 | 38 | ||
34 | XXX Security Advisory for GitLab | 39 | XXX Security Advisory for GitLab |
35 | 40 | ||
36 | A recently discovered critical vulnerability in GitLab allows [unauthenticated API access|remote code execution|unauthorized access to repositories|XXX|PICKSOMETHING]. All users should update GitLab and gitlab-shell immediately. | 41 | A recently discovered critical vulnerability in GitLab allows [unauthenticated API access|remote code execution|unauthorized access to repositories|XXX|PICKSOMETHING]. All users should update GitLab and gitlab-shell immediately. |
42 | +We [have|haven't|XXX|PICKSOMETHING|] heard of this vulnerability being actively exploited. | ||
37 | 43 | ||
38 | ### Version affected | 44 | ### Version affected |
39 | 45 |
features/steps/snippets/snippets.rb
@@ -19,7 +19,7 @@ class SnippetsFeature < Spinach::FeatureSteps | @@ -19,7 +19,7 @@ class SnippetsFeature < Spinach::FeatureSteps | ||
19 | end | 19 | end |
20 | 20 | ||
21 | And 'I click link "Destroy"' do | 21 | And 'I click link "Destroy"' do |
22 | - click_link "Destroy" | 22 | + click_link "Remove" |
23 | end | 23 | end |
24 | 24 | ||
25 | And 'I submit new snippet "Personal snippet three"' do | 25 | And 'I submit new snippet "Personal snippet three"' do |
@@ -46,7 +46,7 @@ class SnippetsFeature < Spinach::FeatureSteps | @@ -46,7 +46,7 @@ class SnippetsFeature < Spinach::FeatureSteps | ||
46 | end | 46 | end |
47 | 47 | ||
48 | And 'I uncheck "Private" checkbox' do | 48 | And 'I uncheck "Private" checkbox' do |
49 | - find(:xpath, "//input[@id='personal_snippet_private']").set true | 49 | + choose "Public" |
50 | click_button "Save" | 50 | click_button "Save" |
51 | end | 51 | end |
52 | 52 |
lib/api/files.rb
@@ -40,8 +40,7 @@ module API | @@ -40,8 +40,7 @@ module API | ||
40 | # Update existing file in repository | 40 | # Update existing file in repository |
41 | # | 41 | # |
42 | # Parameters: | 42 | # Parameters: |
43 | - # file_name (required) - The name of new file. Ex. class.rb | ||
44 | - # file_path (optional) - The path to new file. Ex. lib/ | 43 | + # file_path (optional) - The path to file. Ex. lib/class.rb |
45 | # branch_name (required) - The name of branch | 44 | # branch_name (required) - The name of branch |
46 | # content (required) - File content | 45 | # content (required) - File content |
47 | # commit_message (required) - Commit message | 46 | # commit_message (required) - Commit message |
@@ -67,7 +66,36 @@ module API | @@ -67,7 +66,36 @@ module API | ||
67 | render_api_error!(result[:error], 400) | 66 | render_api_error!(result[:error], 400) |
68 | end | 67 | end |
69 | end | 68 | end |
69 | + | ||
70 | + # Delete existing file in repository | ||
71 | + # | ||
72 | + # Parameters: | ||
73 | + # file_path (optional) - The path to file. Ex. lib/class.rb | ||
74 | + # branch_name (required) - The name of branch | ||
75 | + # content (required) - File content | ||
76 | + # commit_message (required) - Commit message | ||
77 | + # | ||
78 | + # Example Request: | ||
79 | + # DELETE /projects/:id/repository/files | ||
80 | + # | ||
81 | + delete ":id/repository/files" do | ||
82 | + required_attributes! [:file_path, :branch_name, :commit_message] | ||
83 | + attrs = attributes_for_keys [:file_path, :branch_name, :commit_message] | ||
84 | + branch_name = attrs.delete(:branch_name) | ||
85 | + file_path = attrs.delete(:file_path) | ||
86 | + result = ::Files::DeleteContext.new(user_project, current_user, attrs, branch_name, file_path).execute | ||
87 | + | ||
88 | + if result[:status] == :success | ||
89 | + status(200) | ||
90 | + | ||
91 | + { | ||
92 | + file_path: file_path, | ||
93 | + branch_name: branch_name | ||
94 | + } | ||
95 | + else | ||
96 | + render_api_error!(result[:error], 400) | ||
97 | + end | ||
98 | + end | ||
70 | end | 99 | end |
71 | end | 100 | end |
72 | end | 101 | end |
73 | - |
lib/api/projects.rb
@@ -31,6 +31,16 @@ module API | @@ -31,6 +31,16 @@ module API | ||
31 | present @projects, with: Entities::Project | 31 | present @projects, with: Entities::Project |
32 | end | 32 | end |
33 | 33 | ||
34 | + # Get all projects for admin user | ||
35 | + # | ||
36 | + # Example Request: | ||
37 | + # GET /projects/all | ||
38 | + get '/all' do | ||
39 | + authenticated_as_admin! | ||
40 | + @projects = paginate Project | ||
41 | + present @projects, with: Entities::Project | ||
42 | + end | ||
43 | + | ||
34 | # Get a single project | 44 | # Get a single project |
35 | # | 45 | # |
36 | # Parameters: | 46 | # Parameters: |
@@ -0,0 +1,43 @@ | @@ -0,0 +1,43 @@ | ||
1 | +require_relative 'file_action' | ||
2 | + | ||
3 | +module Gitlab | ||
4 | + module Satellite | ||
5 | + class DeleteFileAction < FileAction | ||
6 | + # Deletes file and creates a new commit for it | ||
7 | + # | ||
8 | + # Returns false if committing the change fails | ||
9 | + # Returns false if pushing from the satellite to bare repo failed or was rejected | ||
10 | + # Returns true otherwise | ||
11 | + def commit!(content, commit_message) | ||
12 | + in_locked_and_timed_satellite do |repo| | ||
13 | + prepare_satellite!(repo) | ||
14 | + | ||
15 | + # create target branch in satellite at the corresponding commit from bare repo | ||
16 | + repo.git.checkout({raise: true, timeout: true, b: true}, ref, "origin/#{ref}") | ||
17 | + | ||
18 | + # update the file in the satellite's working dir | ||
19 | + file_path_in_satellite = File.join(repo.working_dir, file_path) | ||
20 | + File.delete(file_path_in_satellite) | ||
21 | + | ||
22 | + # add removed file | ||
23 | + repo.remove(file_path_in_satellite) | ||
24 | + | ||
25 | + # commit the changes | ||
26 | + # will raise CommandFailed when commit fails | ||
27 | + repo.git.commit(raise: true, timeout: true, a: true, m: commit_message) | ||
28 | + | ||
29 | + | ||
30 | + # push commit back to bare repo | ||
31 | + # will raise CommandFailed when push fails | ||
32 | + repo.git.push({raise: true, timeout: true}, :origin, ref) | ||
33 | + | ||
34 | + # everything worked | ||
35 | + true | ||
36 | + end | ||
37 | + rescue Grit::Git::CommandFailed => ex | ||
38 | + Gitlab::GitLogger.error(ex.message) | ||
39 | + false | ||
40 | + end | ||
41 | + end | ||
42 | + end | ||
43 | +end |
lib/gitlab/satellite/files/edit_file_action.rb
@@ -8,13 +8,13 @@ module Gitlab | @@ -8,13 +8,13 @@ module Gitlab | ||
8 | # | 8 | # |
9 | # Returns false if the ref has been updated while editing the file | 9 | # Returns false if the ref has been updated while editing the file |
10 | # Returns false if committing the change fails | 10 | # Returns false if committing the change fails |
11 | - # Returns false if pushing from the satellite to Gitolite failed or was rejected | 11 | + # Returns false if pushing from the satellite to bare repo failed or was rejected |
12 | # Returns true otherwise | 12 | # Returns true otherwise |
13 | def commit!(content, commit_message) | 13 | def commit!(content, commit_message) |
14 | in_locked_and_timed_satellite do |repo| | 14 | in_locked_and_timed_satellite do |repo| |
15 | prepare_satellite!(repo) | 15 | prepare_satellite!(repo) |
16 | 16 | ||
17 | - # create target branch in satellite at the corresponding commit from Gitolite | 17 | + # create target branch in satellite at the corresponding commit from bare repo |
18 | repo.git.checkout({raise: true, timeout: true, b: true}, ref, "origin/#{ref}") | 18 | repo.git.checkout({raise: true, timeout: true, b: true}, ref, "origin/#{ref}") |
19 | 19 | ||
20 | # update the file in the satellite's working dir | 20 | # update the file in the satellite's working dir |
@@ -26,7 +26,7 @@ module Gitlab | @@ -26,7 +26,7 @@ module Gitlab | ||
26 | repo.git.commit(raise: true, timeout: true, a: true, m: commit_message) | 26 | repo.git.commit(raise: true, timeout: true, a: true, m: commit_message) |
27 | 27 | ||
28 | 28 | ||
29 | - # push commit back to Gitolite | 29 | + # push commit back to bare repo |
30 | # will raise CommandFailed when push fails | 30 | # will raise CommandFailed when push fails |
31 | repo.git.push({raise: true, timeout: true}, :origin, ref) | 31 | repo.git.push({raise: true, timeout: true}, :origin, ref) |
32 | 32 |
lib/gitlab/satellite/files/new_file_action.rb
@@ -7,13 +7,13 @@ module Gitlab | @@ -7,13 +7,13 @@ module Gitlab | ||
7 | # | 7 | # |
8 | # Returns false if the ref has been updated while editing the file | 8 | # Returns false if the ref has been updated while editing the file |
9 | # Returns false if committing the change fails | 9 | # Returns false if committing the change fails |
10 | - # Returns false if pushing from the satellite to Gitolite failed or was rejected | 10 | + # Returns false if pushing from the satellite to bare repo failed or was rejected |
11 | # Returns true otherwise | 11 | # Returns true otherwise |
12 | def commit!(content, commit_message) | 12 | def commit!(content, commit_message) |
13 | in_locked_and_timed_satellite do |repo| | 13 | in_locked_and_timed_satellite do |repo| |
14 | prepare_satellite!(repo) | 14 | prepare_satellite!(repo) |
15 | 15 | ||
16 | - # create target branch in satellite at the corresponding commit from Gitolite | 16 | + # create target branch in satellite at the corresponding commit from bare repo |
17 | repo.git.checkout({raise: true, timeout: true, b: true}, ref, "origin/#{ref}") | 17 | repo.git.checkout({raise: true, timeout: true, b: true}, ref, "origin/#{ref}") |
18 | 18 | ||
19 | # update the file in the satellite's working dir | 19 | # update the file in the satellite's working dir |
@@ -28,7 +28,7 @@ module Gitlab | @@ -28,7 +28,7 @@ module Gitlab | ||
28 | repo.git.commit(raise: true, timeout: true, a: true, m: commit_message) | 28 | repo.git.commit(raise: true, timeout: true, a: true, m: commit_message) |
29 | 29 | ||
30 | 30 | ||
31 | - # push commit back to Gitolite | 31 | + # push commit back to bare repo |
32 | # will raise CommandFailed when push fails | 32 | # will raise CommandFailed when push fails |
33 | repo.git.push({raise: true, timeout: true}, :origin, ref) | 33 | repo.git.push({raise: true, timeout: true}, :origin, ref) |
34 | 34 |
lib/gitlab/satellite/merge_action.rb
@@ -28,7 +28,7 @@ module Gitlab | @@ -28,7 +28,7 @@ module Gitlab | ||
28 | in_locked_and_timed_satellite do |merge_repo| | 28 | in_locked_and_timed_satellite do |merge_repo| |
29 | prepare_satellite!(merge_repo) | 29 | prepare_satellite!(merge_repo) |
30 | if merge_in_satellite!(merge_repo) | 30 | if merge_in_satellite!(merge_repo) |
31 | - # push merge back to Gitolite | 31 | + # push merge back to bare repo |
32 | # will raise CommandFailed when push fails | 32 | # will raise CommandFailed when push fails |
33 | merge_repo.git.push(default_options, :origin, merge_request.target_branch) | 33 | merge_repo.git.push(default_options, :origin, merge_request.target_branch) |
34 | # remove source branch | 34 | # remove source branch |
lib/gitlab/satellite/satellite.rb
@@ -123,7 +123,7 @@ module Gitlab | @@ -123,7 +123,7 @@ module Gitlab | ||
123 | remotes.each { |name| repo.git.remote(default_options,'rm', name)} | 123 | remotes.each { |name| repo.git.remote(default_options,'rm', name)} |
124 | end | 124 | end |
125 | 125 | ||
126 | - # Updates the satellite from Gitolite | 126 | + # Updates the satellite from bare repo |
127 | # | 127 | # |
128 | # Note: this will only update remote branches (i.e. origin/*) | 128 | # Note: this will only update remote branches (i.e. origin/*) |
129 | def update_from_source! | 129 | def update_from_source! |
spec/requests/api/files_spec.rb
@@ -78,4 +78,38 @@ describe API::API do | @@ -78,4 +78,38 @@ describe API::API do | ||
78 | response.status.should == 400 | 78 | response.status.should == 400 |
79 | end | 79 | end |
80 | end | 80 | end |
81 | + | ||
82 | + describe "DELETE /projects/:id/repository/files" do | ||
83 | + let(:valid_params) { | ||
84 | + { | ||
85 | + file_path: 'spec/spec_helper.rb', | ||
86 | + branch_name: 'master', | ||
87 | + commit_message: 'Changed file' | ||
88 | + } | ||
89 | + } | ||
90 | + | ||
91 | + it "should delete existing file in project repo" do | ||
92 | + Gitlab::Satellite::DeleteFileAction.any_instance.stub( | ||
93 | + commit!: true, | ||
94 | + ) | ||
95 | + | ||
96 | + delete api("/projects/#{project.id}/repository/files", user), valid_params | ||
97 | + response.status.should == 200 | ||
98 | + json_response['file_path'].should == 'spec/spec_helper.rb' | ||
99 | + end | ||
100 | + | ||
101 | + it "should return a 400 bad request if no params given" do | ||
102 | + delete api("/projects/#{project.id}/repository/files", user) | ||
103 | + response.status.should == 400 | ||
104 | + end | ||
105 | + | ||
106 | + it "should return a 400 if satellite fails to create file" do | ||
107 | + Gitlab::Satellite::DeleteFileAction.any_instance.stub( | ||
108 | + commit!: false, | ||
109 | + ) | ||
110 | + | ||
111 | + delete api("/projects/#{project.id}/repository/files", user), valid_params | ||
112 | + response.status.should == 400 | ||
113 | + end | ||
114 | + end | ||
81 | end | 115 | end |
spec/requests/api/projects_spec.rb
@@ -36,6 +36,32 @@ describe API::API do | @@ -36,6 +36,32 @@ describe API::API do | ||
36 | end | 36 | end |
37 | end | 37 | end |
38 | 38 | ||
39 | + describe "GET /projects/all" do | ||
40 | + context "when unauthenticated" do | ||
41 | + it "should return authentication error" do | ||
42 | + get api("/projects/all") | ||
43 | + response.status.should == 401 | ||
44 | + end | ||
45 | + end | ||
46 | + | ||
47 | + context "when authenticated as regular user" do | ||
48 | + it "should return authentication error" do | ||
49 | + get api("/projects/all", user) | ||
50 | + response.status.should == 403 | ||
51 | + end | ||
52 | + end | ||
53 | + | ||
54 | + context "when authenticated as admin" do | ||
55 | + it "should return an array of all projects" do | ||
56 | + get api("/projects/all", admin) | ||
57 | + response.status.should == 200 | ||
58 | + json_response.should be_an Array | ||
59 | + json_response.first['name'].should == project.name | ||
60 | + json_response.first['owner']['email'].should == user.email | ||
61 | + end | ||
62 | + end | ||
63 | + end | ||
64 | + | ||
39 | describe "POST /projects" do | 65 | describe "POST /projects" do |
40 | context "maximum number of projects reached" do | 66 | context "maximum number of projects reached" do |
41 | before do | 67 | before do |