Commit 12c4fb1b authored by Rémy Coutable's avatar Rémy Coutable

Merge branch 'issue_18585' into 'master'

Allow to disable user request access to groups/projects

fixes #18585 

![projects](/uploads/9f381e77ffbcd2ecdbabdb8b201b95e4/projects.png)  

![namespaces](/uploads/4b8d39c80576b499118373f0a221882c/namespaces.png)

## Does this MR meet the acceptance criteria?

- [x] [CHANGELOG](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CHANGELOG) entry added
- [x] [Documentation created/updated](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/development/doc_styleguide.md)
- [ ] API support added
- Tests
  - [x] Added for this feature/bug
  - [x] All builds are passing
- [x] Conform by the [style guides](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#style-guides)
- [x] Branch has no merge conflicts with `master` (if you do - rebase it please)
- [x] [Squashed related commits together](https://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits)

See merge request !5286
parents f4964116 5fb436aa
...@@ -13,6 +13,7 @@ v 8.10.0 (unreleased) ...@@ -13,6 +13,7 @@ v 8.10.0 (unreleased)
- Fix commit builds API, return all builds for all pipelines for given commit. !4849 - Fix commit builds API, return all builds for all pipelines for given commit. !4849
- Replace Haml with Hamlit to make view rendering faster. !3666 - Replace Haml with Hamlit to make view rendering faster. !3666
- Refresh the branch cache after `git gc` runs - Refresh the branch cache after `git gc` runs
- Allow to disable request access button on projects/groups
- Refactor repository paths handling to allow multiple git mount points - Refactor repository paths handling to allow multiple git mount points
- Optimize system note visibility checking by memoizing the visible reference count !5070 - Optimize system note visibility checking by memoizing the visible reference count !5070
- Add Application Setting to configure default Repository Path for new projects - Add Application Setting to configure default Repository Path for new projects
......
...@@ -60,6 +60,6 @@ class Admin::GroupsController < Admin::ApplicationController ...@@ -60,6 +60,6 @@ class Admin::GroupsController < Admin::ApplicationController
end end
def group_params def group_params
params.require(:group).permit(:name, :description, :path, :avatar, :visibility_level) params.require(:group).permit(:name, :description, :path, :avatar, :visibility_level, :request_access_enabled)
end end
end end
...@@ -121,7 +121,7 @@ class GroupsController < Groups::ApplicationController ...@@ -121,7 +121,7 @@ class GroupsController < Groups::ApplicationController
end end
def group_params def group_params
params.require(:group).permit(:name, :description, :path, :avatar, :public, :visibility_level, :share_with_group_lock) params.require(:group).permit(:name, :description, :path, :avatar, :public, :visibility_level, :share_with_group_lock, :request_access_enabled)
end end
def load_events def load_events
......
...@@ -296,7 +296,7 @@ class ProjectsController < Projects::ApplicationController ...@@ -296,7 +296,7 @@ class ProjectsController < Projects::ApplicationController
:issues_tracker_id, :default_branch, :issues_tracker_id, :default_branch,
:wiki_enabled, :visibility_level, :import_url, :last_activity_at, :namespace_id, :avatar, :wiki_enabled, :visibility_level, :import_url, :last_activity_at, :namespace_id, :avatar,
:builds_enabled, :build_allow_git_fetch, :build_timeout_in_minutes, :build_coverage_regex, :builds_enabled, :build_allow_git_fetch, :build_timeout_in_minutes, :build_coverage_regex,
:public_builds, :only_allow_merge_if_build_succeeds :public_builds, :only_allow_merge_if_build_succeeds, :request_access_enabled
) )
end end
......
...@@ -172,7 +172,7 @@ class Ability ...@@ -172,7 +172,7 @@ class Ability
rules << :read_build if project.public_builds? rules << :read_build if project.public_builds?
unless owner || project.team.member?(user) || project_group_member?(project, user) unless owner || project.team.member?(user) || project_group_member?(project, user)
rules << :request_access rules << :request_access if project.request_access_enabled
end end
end end
...@@ -373,7 +373,7 @@ class Ability ...@@ -373,7 +373,7 @@ class Ability
end end
if group.public? || (group.internal? && !user.external?) if group.public? || (group.internal? && !user.external?)
rules << :request_access unless group.users.include?(user) rules << :request_access if group.request_access_enabled && group.users.exclude?(user)
end end
rules.flatten rules.flatten
......
...@@ -9,6 +9,10 @@ ...@@ -9,6 +9,10 @@
= render 'shared/visibility_level', f: f, visibility_level: @group.visibility_level, can_change_visibility_level: can_change_group_visibility_level?(@group), form_model: @group = render 'shared/visibility_level', f: f, visibility_level: @group.visibility_level, can_change_visibility_level: can_change_group_visibility_level?(@group), form_model: @group
.form-group
.col-sm-offset-2.col-sm-10
= render 'shared/allow_request_access', form: f
- if @group.new_record? - if @group.new_record?
.form-group .form-group
.col-sm-offset-2.col-sm-10 .col-sm-offset-2.col-sm-10
......
...@@ -21,6 +21,10 @@ ...@@ -21,6 +21,10 @@
= render 'shared/visibility_level', f: f, visibility_level: @group.visibility_level, can_change_visibility_level: can_change_group_visibility_level?(@group), form_model: @group = render 'shared/visibility_level', f: f, visibility_level: @group.visibility_level, can_change_visibility_level: can_change_group_visibility_level?(@group), form_model: @group
.form-group
.col-sm-offset-2.col-sm-10
= render 'shared/allow_request_access', form: f
.form-group .form-group
%hr %hr
= f.label :share_with_group_lock, class: 'control-label' do = f.label :share_with_group_lock, class: 'control-label' do
......
...@@ -32,6 +32,10 @@ ...@@ -32,6 +32,10 @@
%strong %strong
= visibility_level_label(@project.visibility_level) = visibility_level_label(@project.visibility_level)
.light= visibility_level_description(@project.visibility_level, @project) .light= visibility_level_description(@project.visibility_level, @project)
.form-group
= render 'shared/allow_request_access', form: f
.form-group .form-group
= f.label :tag_list, "Tags", class: 'label-light' = f.label :tag_list, "Tags", class: 'label-light'
= f.text_field :tag_list, value: @project.tag_list.to_s, maxlength: 2000, class: "form-control" = f.text_field :tag_list, value: @project.tag_list.to_s, maxlength: 2000, class: "form-control"
......
.checkbox
= form.label :request_access_enabled do
= form.check_box :request_access_enabled
%strong Allow users to request access
%br
%span.descr Allow users to request access if visibility is public or internal.
class AddRequestAccessEnabledToProjects < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
disable_ddl_transaction!
def up
add_column_with_default :projects, :request_access_enabled, :boolean, default: true
end
def down
remove_column :projects, :request_access_enabled
end
end
class AddRequestAccessEnabledToGroups < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
disable_ddl_transaction!
def up
add_column_with_default :namespaces, :request_access_enabled, :boolean, default: true
end
def down
remove_column :namespaces, :request_access_enabled
end
end
...@@ -674,6 +674,7 @@ ActiveRecord::Schema.define(version: 20160718153603) do ...@@ -674,6 +674,7 @@ ActiveRecord::Schema.define(version: 20160718153603) do
t.string "avatar" t.string "avatar"
t.boolean "share_with_group_lock", default: false t.boolean "share_with_group_lock", default: false
t.integer "visibility_level", default: 20, null: false t.integer "visibility_level", default: 20, null: false
t.boolean "request_access_enabled", default: true, null: false
end end
add_index "namespaces", ["created_at", "id"], name: "index_namespaces_on_created_at_and_id", using: :btree add_index "namespaces", ["created_at", "id"], name: "index_namespaces_on_created_at_and_id", using: :btree
...@@ -843,6 +844,7 @@ ActiveRecord::Schema.define(version: 20160718153603) do ...@@ -843,6 +844,7 @@ ActiveRecord::Schema.define(version: 20160718153603) do
t.boolean "has_external_issue_tracker" t.boolean "has_external_issue_tracker"
t.string "repository_storage", default: "default", null: false t.string "repository_storage", default: "default", null: false
t.boolean "has_external_wiki" t.boolean "has_external_wiki"
t.boolean "request_access_enabled", default: true, null: false
end end
add_index "projects", ["builds_enabled", "shared_runners_enabled"], name: "index_projects_on_builds_enabled_and_shared_runners_enabled", using: :btree add_index "projects", ["builds_enabled", "shared_runners_enabled"], name: "index_projects_on_builds_enabled_and_shared_runners_enabled", using: :btree
......
...@@ -90,6 +90,9 @@ GitLab account using the same e-mail address the invitation was sent to. ...@@ -90,6 +90,9 @@ GitLab account using the same e-mail address the invitation was sent to.
## Request access to a project ## Request access to a project
As a project owner you can enable or disable non members to request access to
your project. Go to the project settings and click on **Allow users to request access**.
As a user, you can request to be a member of a project. Go to the project you'd As a user, you can request to be a member of a project. Go to the project you'd
like to be a member of, and click the **Request Access** button on the right like to be a member of, and click the **Request Access** button on the right
side of your screen. side of your screen.
......
...@@ -53,6 +53,9 @@ If necessary, you can increase the access level of an individual user for a spec ...@@ -53,6 +53,9 @@ If necessary, you can increase the access level of an individual user for a spec
## Requesting access to a group ## Requesting access to a group
As a group owner you can enable or disable non members to request access to
your group. Go to the group settings and click on **Allow users to request access**.
As a user, you can request to be a member of a group. Go to the group you'd As a user, you can request to be a member of a group. Go to the group you'd
like to be a member of, and click the **Request Access** button on the right like to be a member of, and click the **Request Access** button on the right
side of your screen. side of your screen.
......
...@@ -12,6 +12,13 @@ feature 'Groups > Members > User requests access', feature: true do ...@@ -12,6 +12,13 @@ feature 'Groups > Members > User requests access', feature: true do
visit group_path(group) visit group_path(group)
end end
scenario 'request access feature is disabled' do
group.update_attributes(request_access_enabled: false)
visit group_path(group)
expect(page).not_to have_content 'Request Access'
end
scenario 'user can request access to a group' do scenario 'user can request access to a group' do
perform_enqueued_jobs { click_link 'Request Access' } perform_enqueued_jobs { click_link 'Request Access' }
......
...@@ -11,6 +11,13 @@ feature 'Projects > Members > User requests access', feature: true do ...@@ -11,6 +11,13 @@ feature 'Projects > Members > User requests access', feature: true do
visit namespace_project_path(project.namespace, project) visit namespace_project_path(project.namespace, project)
end end
scenario 'request access feature is disabled' do
project.update_attributes(request_access_enabled: false)
visit namespace_project_path(project.namespace, project)
expect(page).not_to have_content 'Request Access'
end
scenario 'user can request access to a project' do scenario 'user can request access to a project' do
perform_enqueued_jobs { click_link 'Request Access' } perform_enqueued_jobs { click_link 'Request Access' }
......
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