diff --git a/CHANGELOG b/CHANGELOG index c1107717fc8dd4cae1906103c8b27234f3b29b2d..c4e411e2df54658dc3ef197ab9874006185ab918 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -12,6 +12,7 @@ v 6.2.0 - Update logic for validates_merge_request for tree of MR (Andrew Kumanyaev) - Rake tasks for web hooks management (Jonhnny Weslley) - Extended User API to expose admin and can_create_group for user creation/updating (Boyan Tabakov) + - API: Remove group v 6.1.0 - Project specific IDs for issues, mr, milestones diff --git a/app/assets/stylesheets/sections/tree.scss b/app/assets/stylesheets/sections/tree.scss index 2a84741f0d61a21b66e6c8e91b0aa22a23b70ba1..96f2a5711fa139749fbda31aaa823dbbae66a0cf 100644 --- a/app/assets/stylesheets/sections/tree.scss +++ b/app/assets/stylesheets/sections/tree.scss @@ -65,11 +65,6 @@ .tree_author { padding-right: 8px; - - img.avatar { - margin-top: 0; - width: 16px; - } } .tree_commit { diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb index 39cd579cce5b75b38eaa0016e7d8712c9496118a..3e88656cdf159fad6ea70c89d648129253b2d61f 100644 --- a/app/controllers/projects/milestones_controller.rb +++ b/app/controllers/projects/milestones_controller.rb @@ -14,7 +14,7 @@ class Projects::MilestonesController < Projects::ApplicationController @milestones = case params[:f] when 'all'; @project.milestones.order("state, due_date DESC") when 'closed'; @project.milestones.closed.order("due_date DESC") - else @project.milestones.active.order("due_date DESC") + else @project.milestones.active.order("due_date ASC") end @milestones = @milestones.includes(:project) diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index a26190015b2cb1fdf55017b106ddc1c1e76b52b9..b164ea11073d97681c39a75eec829c1a5cceb9da 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -222,7 +222,11 @@ class MergeRequest < ActiveRecord::Base def mr_and_commit_notes commit_ids = commits.map(&:id) - Note.where("(noteable_type = 'MergeRequest' AND noteable_id = :mr_id) OR (noteable_type = 'Commit' AND commit_id IN (:commit_ids))", mr_id: id, commit_ids: commit_ids) + project.notes.where( + "(noteable_type = 'MergeRequest' AND noteable_id = :mr_id) OR (noteable_type = 'Commit' AND commit_id IN (:commit_ids))", + mr_id: id, + commit_ids: commit_ids + ) end # Returns the raw diff for this merge request diff --git a/app/models/project.rb b/app/models/project.rb index 8755ffa69b881d2e8f837d58993f81509ee2142c..d2dcf26ac69bec0749db92ed6de9f4e43dc3f3a1 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -53,6 +53,7 @@ class Project < ActiveRecord::Base has_many :services, dependent: :destroy has_many :events, dependent: :destroy has_many :merge_requests, dependent: :destroy, foreign_key: "target_project_id" + has_many :fork_merge_requests,dependent: :destroy, foreign_key: "source_project_id", class_name: MergeRequest has_many :issues, dependent: :destroy, order: "state DESC, created_at DESC" has_many :milestones, dependent: :destroy has_many :notes, dependent: :destroy @@ -312,8 +313,11 @@ class Project < ActiveRecord::Base branch_name = ref.gsub("refs/heads/", "") c_ids = self.repository.commits_between(oldrev, newrev).map(&:id) - # Update code for merge requests + # Update code for merge requests into project between project branches mrs = self.merge_requests.opened.by_branch(branch_name).all + # Update code for merge requests between project and project fork + mrs += self.fork_merge_requests.opened.by_branch(branch_name).all + mrs.each { |merge_request| merge_request.reload_code; merge_request.mark_as_unchecked } # Close merge requests diff --git a/app/services/system_hooks_service.rb b/app/services/system_hooks_service.rb index 39aec943f75596a82c3e6f5e2a34986f31a30603..de4fa9b79e72aa55a8728eea6e00716875e680c2 100644 --- a/app/services/system_hooks_service.rb +++ b/app/services/system_hooks_service.rb @@ -36,7 +36,8 @@ class SystemHooksService when User data.merge!({ name: model.name, - email: model.email + email: model.email, + user_id: model.id }) when UsersProject data.merge!({ diff --git a/app/views/admin/hooks/_data_ex.html.erb b/app/views/admin/hooks/_data_ex.html.erb index b69aa92716dc9444e98b0c845b487c23efce5c39..5b16dfb398a12c1ec40a691a02bef22c699e0dbf 100644 --- a/app/views/admin/hooks/_data_ex.html.erb +++ b/app/views/admin/hooks/_data_ex.html.erb @@ -52,7 +52,8 @@ "created_at": "2012-07-21T07:44:07Z", "email": "js@gitlabhq.com", "event_name": "user_create", - "name": "John Smith" + "name": "John Smith", + "user_id": 41 } 6. User removed: @@ -60,7 +61,8 @@ "created_at": "2012-07-21T07:44:07Z", "email": "js@gitlabhq.com", "event_name": "user_destroy", - "name": "John Smith" + "name": "John Smith", + "user_id": 41 } eos diff --git a/app/views/admin/hooks/index.html.haml b/app/views/admin/hooks/index.html.haml index eb6570af30e2a271341b89f0d3ae94b668813f0c..1bd7b8eac622eea89da62dadfb4ad451766f6519 100644 --- a/app/views/admin/hooks/index.html.haml +++ b/app/views/admin/hooks/index.html.haml @@ -1,9 +1,12 @@ -.alert.alert-info - %span - Post-receive hooks for binding events. - %br - Read more about system hooks - %strong #{link_to "here", help_system_hooks_path, class: "vlink"} +%h3.page-title + System Hooks + +%p.light + #{link_to "System hooks ", help_system_hooks_path, class: "vlink"} can be + used for binding events when GitLab creates a User or Project. + +%hr + = form_for @hook, as: :hook, url: admin_hooks_path, html: { class: 'form-inline' } do |f| -if @hook.errors.any? diff --git a/app/views/projects/tree/_tree_commit_column.html.haml b/app/views/projects/tree/_tree_commit_column.html.haml index 7ae2582c130af4537208212f692f8708452860d0..67b5b2b96e280f8eee69e56a62ac78f7ec2a3bfc 100644 --- a/app/views/projects/tree/_tree_commit_column.html.haml +++ b/app/views/projects/tree/_tree_commit_column.html.haml @@ -1,2 +1,2 @@ -%span.tree_author= commit_author_link(commit, avatar: true) +%span.tree_author= commit_author_link(commit, avatar: true, size: 16) = link_to_gfm truncate(commit.title, length: 80), project_commit_path(@project, commit.id), class: "tree-commit-link" diff --git a/doc/api/groups.md b/doc/api/groups.md index f56c534667a533257d062ff47cbcc07800a71a36..f5f5d7690509cccd3184caefb53284d4c32222b2 100644 --- a/doc/api/groups.md +++ b/doc/api/groups.md @@ -57,6 +57,19 @@ Parameters: + `project_id` (required) - The ID of a project +## Remove group + +Removes group with all projects inside. + +``` +DELETE /groups/:id +``` + +Parameters: + ++ `id` (required) - The ID of a user group + + ## Group members diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md index e69d4bc99b984a39c990edeaf82a01cdb773cf71..dae12f03ef5e9682bfcc1b5952162cdf273cd645 100644 --- a/doc/api/merge_requests.md +++ b/doc/api/merge_requests.md @@ -20,6 +20,8 @@ Parameters: "project_id":3, "title":"test1", "state":"opened", + "upvotes":0, + "downvotes":0, "author":{ "id":1, "username": "admin", @@ -62,6 +64,8 @@ Parameters: "project_id":3, "title":"test1", "state":"merged", + "upvotes":0, + "downvotes":0, "author":{ "id":1, "username": "admin", @@ -106,6 +110,8 @@ Parameters: "project_id":3, "title":"test1", "state":"opened", + "upvotes":0, + "downvotes":0, "author":{ "id":1, "username": "admin", @@ -152,6 +158,8 @@ Parameters: "project_id":3, "title":"test1", "state":"opened", + "upvotes":0, + "downvotes":0, "author":{ "id":1, "username": "admin", diff --git a/doc/update/5.1-to-5.2.md b/doc/update/5.1-to-5.2.md index 8599c4323eae0a41cc07c17db40add1f29cf089d..27f992ecfe6831436ed4c48cb9620859f76d1b4c 100644 --- a/doc/update/5.1-to-5.2.md +++ b/doc/update/5.1-to-5.2.md @@ -7,7 +7,7 @@ It's useful to make a backup just in case things go south: ```bash cd /home/git/gitlab -sudo -u git -H RAILS_ENV=production bundle exec rake gitlab:backup:create +sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production ``` ### 1. Stop server @@ -95,5 +95,5 @@ Follow the [`upgrade guide from 5.0 to 5.1`](5.0-to-5.1.md), except for the data ```bash cd /home/git/gitlab -sudo -u git -H RAILS_ENV=production bundle exec rake gitlab:backup:restore +sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production ``` diff --git a/doc/update/5.2-to-5.3.md b/doc/update/5.2-to-5.3.md index e00dfa3951a47f79bb0d09274b4e98f8ab5ede4d..a8bb530902c37fa11c63bf8bbaaef1b2c42da6f4 100644 --- a/doc/update/5.2-to-5.3.md +++ b/doc/update/5.2-to-5.3.md @@ -7,7 +7,7 @@ It's useful to make a backup just in case things go south: ```bash cd /home/git/gitlab -sudo -u git -H RAILS_ENV=production bundle exec rake gitlab:backup:create +sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production ``` ### 1. Stop server @@ -78,5 +78,5 @@ Follow the [`upgrade guide from 5.1 to 5.2`](5.1-to-5.2.md), except for the data ```bash cd /home/git/gitlab -sudo -u git -H RAILS_ENV=production bundle exec rake gitlab:backup:restore +sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production ``` diff --git a/doc/update/5.3-to-5.4.md b/doc/update/5.3-to-5.4.md index 5fba0e26afa437727f281bca4df1b250ce03c4e0..315bf03a6deb5fb0169377bd2e12a60764802ce0 100644 --- a/doc/update/5.3-to-5.4.md +++ b/doc/update/5.3-to-5.4.md @@ -7,7 +7,7 @@ It's useful to make a backup just in case things go south: ```bash cd /home/git/gitlab -sudo -u git -H RAILS_ENV=production bundle exec rake gitlab:backup:create +sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production ``` ### 1. Stop server @@ -86,5 +86,5 @@ Follow the [`upgrade guide from 5.2 to 5.3`](5.2-to-5.3.md), except for the data ```bash cd /home/git/gitlab -sudo -u git -H RAILS_ENV=production bundle exec rake gitlab:backup:restore +sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production ``` diff --git a/doc/update/5.4-to-6.0.md b/doc/update/5.4-to-6.0.md index 3b1d9878204b41f734ce64891688944866b29dc3..0027d91d60aca886d08ac0edb82ca961ece3ac76 100644 --- a/doc/update/5.4-to-6.0.md +++ b/doc/update/5.4-to-6.0.md @@ -24,7 +24,7 @@ It's useful to make a backup just in case things go south: ```bash cd /home/git/gitlab -sudo -u git -H RAILS_ENV=production bundle exec rake gitlab:backup:create +sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production ``` ### 1. Stop server diff --git a/doc/update/6.0-to-6.1.md b/doc/update/6.0-to-6.1.md index 9ec99af205b8315504ea047c6654420f00e8c6a9..c3851a10df00ebbf81c750a47f7407b3bbd753ca 100644 --- a/doc/update/6.0-to-6.1.md +++ b/doc/update/6.0-to-6.1.md @@ -16,7 +16,7 @@ It's useful to make a backup just in case things go south: ```bash cd /home/git/gitlab -sudo -u git -H RAILS_ENV=production bundle exec rake gitlab:backup:create +sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production ``` ### 1. Stop server @@ -99,5 +99,5 @@ Follow the [`upgrade guide from 5.4 to 6.0`](5.4-to-6.0.md), except for the data ```bash cd /home/git/gitlab -sudo -u git -H RAILS_ENV=production bundle exec rake gitlab:backup:restore +sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production ``` diff --git a/doc/update/6.1-to-6.2.md b/doc/update/6.1-to-6.2.md index 747b4860796672da837058cf16319509b0dbf98d..9f3a869a0ee1874225ba8c35bed5cdc9ec672fcf 100644 --- a/doc/update/6.1-to-6.2.md +++ b/doc/update/6.1-to-6.2.md @@ -9,7 +9,7 @@ It's useful to make a backup just in case things go south: ```bash cd /home/git/gitlab -sudo -u git -H RAILS_ENV=production bundle exec rake gitlab:backup:create +sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production ``` ### 1. Stop server @@ -96,5 +96,5 @@ Follow the [`upgrade guide from 6.0 to 6.1`](6.0-to-6.1.md), except for the data ```bash cd /home/git/gitlab -sudo -u git -H RAILS_ENV=production bundle exec rake gitlab:backup:restore +sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production ``` diff --git a/lib/api/entities.rb b/lib/api/entities.rb index ab949f530ab74f365da34b99324eb90aaff2e2e8..b4771eecc7f713f4a7ca2a422271655073e96dc5 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -112,7 +112,7 @@ module API end class MergeRequest < Grape::Entity - expose :id, :target_branch, :source_branch, :title, :state + expose :id, :target_branch, :source_branch, :title, :state, :upvotes, :downvotes expose :target_project_id, as: :project_id expose :author, :assignee, using: Entities::UserBasic end diff --git a/lib/api/groups.rb b/lib/api/groups.rb index 396554404af4d7d12f29c87ac889d541fdf49d15..265417fd6bcd0dfc4762fda27d7821c89d0d10bb 100644 --- a/lib/api/groups.rb +++ b/lib/api/groups.rb @@ -7,12 +7,14 @@ module API helpers do def find_group(id) group = Group.find(id) - if current_user.admin or current_user.groups.include? group + + if can?(current_user, :read_group, group) group else render_api_error!("403 Forbidden - #{current_user.username} lacks sufficient access to #{group.name}", 403) end end + def validate_access_level?(level) Gitlab::Access.options_with_owner.values.include? level.to_i end @@ -64,6 +66,19 @@ module API present group, with: Entities::GroupDetail end + + # Remove group + # + # Parameters: + # id (required) - The ID of a group + # Example Request: + # DELETE /groups/:id + delete ":id" do + group = find_group(params[:id]) + authorize! :manage_group, group + group.destroy + end + # Transfer a project to the Group namespace # # Parameters: @@ -132,7 +147,6 @@ module API member.destroy end end - end end end diff --git a/lib/api/internal.rb b/lib/api/internal.rb index 79f8eb3a543adfe20766738e4a110969ad262491..ed6b50c3a6a4986204fd2baf6ca89052b8419830 100644 --- a/lib/api/internal.rb +++ b/lib/api/internal.rb @@ -35,6 +35,7 @@ module API user = key.user return false if user.blocked? + return false if user.ldap_user? && Gitlab::LDAP::User.blocked?(user.extern_uid) action = case git_cmd when *DOWNLOAD_COMMANDS diff --git a/lib/gitlab/ldap/user.rb b/lib/gitlab/ldap/user.rb index 260bacfeeb093d79509978496ee684d7fb46e7e8..78fc5dab9cbe439caa4f2e8de1ad7e691963ea3f 100644 --- a/lib/gitlab/ldap/user.rb +++ b/lib/gitlab/ldap/user.rb @@ -71,6 +71,16 @@ module Gitlab find_by_uid(ldap_user.dn) if ldap_user end + # Check LDAP user existance by dn. User in git over ssh check + # + # It covers 2 cases: + # * when ldap account was removed + # * when ldap account was deactivated by change of OU membership in 'dn' + def blocked?(dn) + ldap = OmniAuth::LDAP::Adaptor.new(ldap_conf) + ldap.connection.search(base: dn, size: 1).blank? + end + private def find_by_uid(uid) diff --git a/lib/support/init.d/gitlab b/lib/support/init.d/gitlab index 0248284f8d5efe314aa5443ee873645bc031b9e3..6aff7b5a8f9b3dcd5b8561dc78ebc2a98dfa1a44 100755 --- a/lib/support/init.d/gitlab +++ b/lib/support/init.d/gitlab @@ -151,7 +151,7 @@ stop() { exit_if_not_running # If the Unicorn web server is running, tell it to stop; if [ "$web_status" = "0" ]; then - kill -QUIT "$wpid" & + kill -QUIT "$wpid" echo "Stopping the GitLab Unicorn web server..." stopping=true else @@ -160,7 +160,7 @@ stop() { # And do the same thing for the Sidekiq. if [ "$sidekiq_status" = "0" ]; then printf "Stopping Sidekiq job dispatcher." - RAILS_ENV=$RAILS_ENV bundle exec rake sidekiq:stop & + RAILS_ENV=$RAILS_ENV bundle exec rake sidekiq:stop stopping=true else echo "The Sidekiq was not running, must have run out of breath." diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake index 531b01c4dd513560abb97fe2aefda0949e730ea1..f52b98cb3ae26a7b04e50615af5fa266dda4335b 100644 --- a/lib/tasks/gitlab/check.rake +++ b/lib/tasks/gitlab/check.rake @@ -392,14 +392,20 @@ namespace :gitlab do hook_file = "update" gitlab_shell_hooks_path = Gitlab.config.gitlab_shell.hooks_path gitlab_shell_hook_file = File.join(gitlab_shell_hooks_path, hook_file) - gitlab_shell_ssh_user = Gitlab.config.gitlab_shell.ssh_user - unless File.exists?(gitlab_shell_hook_file) - puts "can't check because of previous errors".magenta - return + if File.exists?(gitlab_shell_hook_file) + puts "yes".green + else + puts "no".red + puts "Could not find #{gitlab_shell_hook_file}" + try_fixing_it( + 'Check the hooks_path in config/gitlab.yml', + 'Check your gitlab-shell installation' + ) + for_more_information( + see_installation_guide_section "GitLab Shell" + ) end - - puts "yes".green end def check_repo_base_exists diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index 703f46adba37f9fa861c79ec9f3c35d1b52947bd..b17183a281c221e797a5146374eb341a06d9193a 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -49,8 +49,8 @@ describe MergeRequest do before do merge_request.stub(:commits) { [merge_request.source_project.repository.commit] } - create(:note, commit_id: merge_request.commits.first.id, noteable_type: 'Commit') - create(:note, noteable: merge_request) + create(:note, commit_id: merge_request.commits.first.id, noteable_type: 'Commit', project: merge_request.project) + create(:note, noteable: merge_request, project: merge_request.project) end it "should include notes for commits" do diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb index a6ce72e11e92a65c0892c8b2e03f433c90a6f588..25b9a10bd8c1f8f6f1a499b3512ddd376244bfa7 100644 --- a/spec/requests/api/groups_spec.rb +++ b/spec/requests/api/groups_spec.rb @@ -106,6 +106,44 @@ describe API::API do end end + describe "DELETE /groups/:id" do + context "when authenticated as user" do + it "should remove group" do + delete api("/groups/#{group1.id}", user1) + response.status.should == 200 + end + + it "should not remove a group if not an owner" do + user3 = create(:user) + group1.add_user(user3, Gitlab::Access::MASTER) + delete api("/groups/#{group1.id}", user3) + response.status.should == 403 + end + + it "should not remove a non existing group" do + delete api("/groups/1328", user1) + response.status.should == 404 + end + + it "should not remove a group not attached to user1" do + delete api("/groups/#{group2.id}", user1) + response.status.should == 403 + end + end + + context "when authenticated as admin" do + it "should remove any existing group" do + delete api("/groups/#{group2.id}", admin) + response.status.should == 200 + end + + it "should not remove a non existing group" do + delete api("/groups/1328", admin) + response.status.should == 404 + end + end + end + describe "POST /groups/:id/projects/:project_id" do let(:project) { create(:project) } before(:each) do diff --git a/spec/services/system_hooks_service_spec.rb b/spec/services/system_hooks_service_spec.rb index 7f1590f559ea097540c86f8be1a37bdf586f4d4a..ebc1ed51d2ede3f116be6f7c869f2a3b6d3d92b1 100644 --- a/spec/services/system_hooks_service_spec.rb +++ b/spec/services/system_hooks_service_spec.rb @@ -5,37 +5,29 @@ describe SystemHooksService do let (:project) { create :project } let (:users_project) { create :users_project } - context 'it should build event data' do - it 'should build event data for user' do - SystemHooksService.build_event_data(user, :create).should include(:event_name, :name, :created_at, :email) - end - - it 'should build event data for project' do - SystemHooksService.build_event_data(project, :create).should include(:event_name, :name, :created_at, :path, :project_id, :owner_name, :owner_email) - end - - it 'should build event data for users project' do - SystemHooksService.build_event_data(users_project, :create).should include(:event_name, :created_at, :project_name, :project_path, :project_id, :user_name, :user_email, :project_access) - end + context 'event data' do + it { event_data(user, :create).should include(:event_name, :name, :created_at, :email, :user_id) } + it { event_data(user, :destroy).should include(:event_name, :name, :created_at, :email, :user_id) } + it { event_data(project, :create).should include(:event_name, :name, :created_at, :path, :project_id, :owner_name, :owner_email) } + it { event_data(project, :destroy).should include(:event_name, :name, :created_at, :path, :project_id, :owner_name, :owner_email) } + it { event_data(users_project, :create).should include(:event_name, :created_at, :project_name, :project_path, :project_id, :user_name, :user_email, :project_access) } + it { event_data(users_project, :destroy).should include(:event_name, :created_at, :project_name, :project_path, :project_id, :user_name, :user_email, :project_access) } end - context 'it should build event names' do - it 'should build event names for user' do - SystemHooksService.build_event_name(user, :create).should eq "user_create" - - SystemHooksService.build_event_name(user, :destroy).should eq "user_destroy" - end - - it 'should build event names for project' do - SystemHooksService.build_event_name(project, :create).should eq "project_create" - - SystemHooksService.build_event_name(project, :destroy).should eq "project_destroy" - end + context 'event names' do + it { event_name(user, :create).should eq "user_create" } + it { event_name(user, :destroy).should eq "user_destroy" } + it { event_name(project, :create).should eq "project_create" } + it { event_name(project, :destroy).should eq "project_destroy" } + it { event_name(users_project, :create).should eq "user_add_to_team" } + it { event_name(users_project, :destroy).should eq "user_remove_from_team" } + end - it 'should build event names for users project' do - SystemHooksService.build_event_name(users_project, :create).should eq "user_add_to_team" + def event_data(*args) + SystemHooksService.build_event_data(*args) + end - SystemHooksService.build_event_name(users_project, :destroy).should eq "user_remove_from_team" - end + def event_name(*args) + SystemHooksService.build_event_name(*args) end end