Commit 23293de2 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'group_membership_lock' into 'master'

Group membership lock

Fixes gitlab/gitlabhq#1591

See merge request !268
parents db49b2d8 6ab5127b
......@@ -2,6 +2,7 @@ v 7.6.0
- Added Audit events related to membership changes for groups and projects
- Added option to attempt a rebase before merging merge request
- Dont show LDAP groups settings if LDAP disabled
- Added member lock for groups to disallow membership additions on project level
- Rebase on merge request. Introduced merge request option to rebase before merging
- Better message for failed pushes because of git hooks
- Kerberos support for web interface and git HTTP
......
......@@ -163,6 +163,6 @@ class GroupsController < ApplicationController
end
def group_params
params.require(:group).permit(:name, :description, :path, :avatar)
params.require(:group).permit(:name, :description, :path, :avatar, :membership_lock)
end
end
......@@ -279,4 +279,12 @@ module ProjectsHelper
result.password = '*****' if result.password.present?
result
end
def membership_locked?
if @project.group && @project.group.membership_lock
true
else
false
end
end
end
......@@ -52,6 +52,7 @@ class ProjectTeam
end
def add_users_ids(user_ids, access)
return false if group_member_lock
ProjectMember.add_users_into_projects(
[project.id],
user_ids,
......@@ -218,4 +219,8 @@ class ProjectTeam
def group
project.group
end
def group_member_lock
group && group.membership_lock
end
end
......@@ -27,6 +27,15 @@
%hr
= link_to 'Remove avatar', group_avatar_path(@group.to_param), data: { confirm: "Group avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-small remove-avatar"
.form-group
%hr
= f.label :name, class: 'control-label' do
Member lock
.col-sm-10
.checkbox
= f.check_box :membership_lock
%span.descr Prevent adding new members to project membership within this group
.form-actions
= f.submit 'Save group', class: "btn btn-save"
......
......@@ -13,5 +13,3 @@
%p
%strong= user.name
%span.cgray= user.username
%h3.page-title
Users with access to this project
- if can? current_user, :admin_team_member, @project
- unless membership_locked?
- if can?(current_user, :admin_team_member, @project)
%span.pull-right
= link_to new_project_team_member_path(@project), class: "btn btn-new btn-grouped", title: "New project member" do
New project member
= link_to import_project_team_members_path(@project), class: "btn btn-grouped", title: "Import members from another project" do
Import members
%p.light
Read more about project permissions
%strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink"
- if membership_locked?
%span.pull-right
Adding new users is disabled at group level
= render "team", members: @project_members
- if @group
= render "group_members"
......
class AddGroupMembershipLock < ActiveRecord::Migration
def change
add_column :namespaces, :membership_lock, :boolean, default: false
end
end
......@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20141205134006) do
ActiveRecord::Schema.define(version: 20141212124604) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
......@@ -265,6 +265,7 @@ ActiveRecord::Schema.define(version: 20141205134006) do
t.string "avatar"
t.string "ldap_cn"
t.integer "ldap_access"
t.boolean "membership_lock", default: false
end
add_index "namespaces", ["name"], name: "index_namespaces_on_name", using: :btree
......
......@@ -69,3 +69,15 @@ gitlab_rails['gitlab_default_can_create_group'] = false
# For installations from source, uncomment the 'default_can_create_group'
# line in /home/git/gitlab/config/gitlab.yml
```
## Lock project membership to members of the group
In GitLab Enterprise Edition it is possible to lock membership in project to the level of members in group.
This allows group owner to lock down any new project membership to any of the projects within the group allowing tighter control over project membership.
To enable this feature, navigate to group settings page, select `Member lock` and `Save group`.
![Checkbox for membership lock](groups/membership_lock.png)
This will disable the option for all users who previously had permissions to operate project memberships so no new users can be added. Furthermore, any request to add new user to project through API will not be possible.
Feature: Groups Management
Background:
Given "Pete Peters" is owner of group "Sourcing"
And "Open" is in group "Sourcing"
And "Mary Jane" has master access for project "Open"
Scenario: Project master can add members before lock
Given I sign in as "Mary Jane"
And I go to "Open" project members page
Then I can control user membership
When Group membership lock is enabled
And I reload "Open" project members page
Then I cannot control user membership from project page
And I logout
Scenario: Group owner lock membership controls
Given I sign in as "Pete Peters"
And I go to group settings page
And I enable membership lock
And I go to project settings
Then I cannot control user membership from project page
And I logout
class Spinach::Features::GroupsManagement < Spinach::FeatureSteps
include SharedAuthentication
include SharedPaths
include SharedGroup
include SharedUser
include Select2Helper
step '"Open" is in group "Sourcing"' do
@group = Group.find_by(name: "Sourcing")
@project ||= create(:project, name: "Open", namespace: @group)
end
step '"Mary Jane" has master access for project "Open"' do
@user = User.find_by(name: "Mary Jane") || create(:user, name: "Mary Jane")
@project = Project.find_by(name: "Open")
@project.team << [@user, :master]
end
step "Group membership lock is enabled" do
@group = Group.find_by(name: "Sourcing")
@group.update_attributes(membership_lock: true)
end
step 'I go to "Open" project members page' do
click_link 'Sourcing / Open'
click_link 'Settings'
click_link 'Members'
end
step 'I can control user membership' do
page.should have_link 'New project member'
page.should have_link 'Import members'
page.should have_selector '#project_member_access_level', text: 'Master'
end
step 'I reload "Open" project members page' do
click_link 'Members'
end
step 'I go to group settings page' do
click_link 'sidebar-groups-tab'
click_link 'Sourcing'
click_link 'Settings'
end
step 'I enable membership lock' do
check 'group_membership_lock'
click_button 'Save group'
end
step 'I go to project settings' do
@project = Project.find_by(name: "Open")
click_link 'Projects'
link = "/#{@project.path_with_namespace}/team"
find(:xpath, "//a[@href=\"#{link}\"]").click
end
step 'I cannot control user membership from project page' do
page.should_not have_link 'New project member'
page.should_not have_link 'Import members'
page.should have_selector '#project_member_access_level', text: 'Master'
end
end
......@@ -20,6 +20,10 @@ module SharedAuthentication
login_with(user_exists("Mary Jane"))
end
step 'I sign in as "Pete Peters"' do
login_with(user_exists("Pete Peters"))
end
step 'I should be redirected to sign in page' do
current_path.should == new_user_session_path
end
......
......@@ -21,6 +21,10 @@ module SharedGroup
is_member_of("Mary Jane", "Guest", Gitlab::Access::GUEST)
end
step '"Pete Peters" is owner of group "Sourcing"' do
is_member_of("Pete Peters", "Sourcing", Gitlab::Access::OWNER)
end
step 'I should see group "TestGroup"' do
page.should have_content "TestGroup"
end
......
......@@ -53,6 +53,10 @@ module API
authorize! :admin_project, user_project
required_attributes! [:user_id, :access_level]
if user_project.group && user_project.group.membership_lock
not_allowed!
end
# either the user is already a team member or a new one
team_member = user_project.team_member_by_id(params[:user_id])
if team_member.nil?
......
......@@ -90,6 +90,18 @@ describe API::API, api: true do
post api("/projects/#{project.id}/members", user), user_id: user2.id, access_level: 1234
response.status.should == 422
end
context 'project in a group' do
before do
project2 = create(:project, group: create(:group, membership_lock: true))
project2.group.add_owner(user)
post api("/projects/#{project2.id}/members", user), user_id: user2.id, access_level: ProjectMember::MASTER
end
it 'should return a 405 method not allowed error when group membership lock is enabled' do
response.status.should == 405
end
end
end
describe "PUT /projects/:id/members/:user_id" do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment