Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
3a770845
Commit
3a770845
authored
Jun 30, 2020
by
Lee Tickett
Committed by
Jan Provaznik
Jun 30, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add requirements visibility access project settings
parent
0d9d2706
Changes
26
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
313 additions
and
48 deletions
+313
-48
app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
...projects/shared/permissions/components/settings_panel.vue
+25
-0
app/assets/javascripts/pages/projects/shared/permissions/mixins/settings_pannel_mixin.js
...ojects/shared/permissions/mixins/settings_pannel_mixin.js
+1
-0
app/controllers/projects_controller.rb
app/controllers/projects_controller.rb
+15
-13
app/models/concerns/featurable.rb
app/models/concerns/featurable.rb
+2
-1
app/models/concerns/project_features_compatibility.rb
app/models/concerns/project_features_compatibility.rb
+2
-0
changelogs/unreleased/add_requirements_visibility_access_project_settings.yml
...d/add_requirements_visibility_access_project_settings.yml
+5
-0
db/migrate/20200615203153_add_requirements_access_level_to_project_features.rb
...3153_add_requirements_access_level_to_project_features.rb
+19
-0
db/structure.sql
db/structure.sql
+3
-1
doc/api/projects.md
doc/api/projects.md
+3
-0
doc/user/project/settings/index.md
doc/user/project/settings/index.md
+1
-0
ee/app/assets/javascripts/pages/projects/shared/permissions/mixins/settings_pannel_mixin.js
...ojects/shared/permissions/mixins/settings_pannel_mixin.js
+1
-0
ee/app/controllers/ee/projects_controller.rb
ee/app/controllers/ee/projects_controller.rb
+5
-0
ee/app/helpers/ee/projects_helper.rb
ee/app/helpers/ee/projects_helper.rb
+8
-2
ee/app/models/concerns/ee/project_features_compatibility.rb
ee/app/models/concerns/ee/project_features_compatibility.rb
+16
-0
ee/app/models/ee/project.rb
ee/app/models/ee/project.rb
+3
-0
ee/app/models/ee/project_feature.rb
ee/app/models/ee/project_feature.rb
+6
-0
ee/app/policies/ee/project_policy.rb
ee/app/policies/ee/project_policy.rb
+1
-1
ee/app/views/layouts/nav/_requirements_link.html.haml
ee/app/views/layouts/nav/_requirements_link.html.haml
+1
-1
ee/lib/ee/api/entities/project.rb
ee/lib/ee/api/entities/project.rb
+3
-0
ee/lib/ee/audit/project_feature_changes_auditor.rb
ee/lib/ee/audit/project_feature_changes_auditor.rb
+2
-1
ee/spec/controllers/projects/requirements_management/requirements_controller_spec.rb
...s/requirements_management/requirements_controller_spec.rb
+100
-28
ee/spec/factories/projects.rb
ee/spec/factories/projects.rb
+4
-0
ee/spec/support/shared_examples/policies/requirement_policy_shared_examples.rb
...d_examples/policies/requirement_policy_shared_examples.rb
+78
-0
locale/gitlab.pot
locale/gitlab.pot
+6
-0
spec/lib/gitlab/import_export/safe_model_attributes.yml
spec/lib/gitlab/import_export/safe_model_attributes.yml
+2
-0
spec/policies/project_policy_spec.rb
spec/policies/project_policy_spec.rb
+1
-0
No files found.
app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
View file @
3a770845
...
@@ -67,6 +67,11 @@ export default {
...
@@ -67,6 +67,11 @@ export default {
required
:
false
,
required
:
false
,
default
:
false
,
default
:
false
,
},
},
requirementsAvailable
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
visibilityHelpPath
:
{
visibilityHelpPath
:
{
type
:
String
,
type
:
String
,
required
:
false
,
required
:
false
,
...
@@ -131,6 +136,7 @@ export default {
...
@@ -131,6 +136,7 @@ export default {
snippetsAccessLevel
:
featureAccessLevel
.
EVERYONE
,
snippetsAccessLevel
:
featureAccessLevel
.
EVERYONE
,
pagesAccessLevel
:
featureAccessLevel
.
EVERYONE
,
pagesAccessLevel
:
featureAccessLevel
.
EVERYONE
,
metricsDashboardAccessLevel
:
featureAccessLevel
.
PROJECT_MEMBERS
,
metricsDashboardAccessLevel
:
featureAccessLevel
.
PROJECT_MEMBERS
,
requirementsAccessLevel
:
featureAccessLevel
.
EVERYONE
,
containerRegistryEnabled
:
true
,
containerRegistryEnabled
:
true
,
lfsEnabled
:
true
,
lfsEnabled
:
true
,
requestAccessEnabled
:
true
,
requestAccessEnabled
:
true
,
...
@@ -233,6 +239,10 @@ export default {
...
@@ -233,6 +239,10 @@ export default {
featureAccessLevel
.
PROJECT_MEMBERS
,
featureAccessLevel
.
PROJECT_MEMBERS
,
this
.
metricsDashboardAccessLevel
,
this
.
metricsDashboardAccessLevel
,
);
);
this
.
requirementsAccessLevel
=
Math
.
min
(
featureAccessLevel
.
PROJECT_MEMBERS
,
this
.
requirementsAccessLevel
,
);
if
(
this
.
pagesAccessLevel
===
featureAccessLevel
.
EVERYONE
)
{
if
(
this
.
pagesAccessLevel
===
featureAccessLevel
.
EVERYONE
)
{
// When from Internal->Private narrow access for only members
// When from Internal->Private narrow access for only members
this
.
pagesAccessLevel
=
featureAccessLevel
.
PROJECT_MEMBERS
;
this
.
pagesAccessLevel
=
featureAccessLevel
.
PROJECT_MEMBERS
;
...
@@ -256,6 +266,9 @@ export default {
...
@@ -256,6 +266,9 @@ export default {
this
.
pagesAccessLevel
=
featureAccessLevel
.
EVERYONE
;
this
.
pagesAccessLevel
=
featureAccessLevel
.
EVERYONE
;
if
(
this
.
metricsDashboardAccessLevel
===
featureAccessLevel
.
PROJECT_MEMBERS
)
if
(
this
.
metricsDashboardAccessLevel
===
featureAccessLevel
.
PROJECT_MEMBERS
)
this
.
metricsDashboardAccessLevel
=
featureAccessLevel
.
EVERYONE
;
this
.
metricsDashboardAccessLevel
=
featureAccessLevel
.
EVERYONE
;
if
(
this
.
requirementsAccessLevel
===
featureAccessLevel
.
PROJECT_MEMBERS
)
this
.
requirementsAccessLevel
=
featureAccessLevel
.
EVERYONE
;
this
.
highlightChanges
();
this
.
highlightChanges
();
}
}
},
},
...
@@ -470,6 +483,18 @@ export default {
...
@@ -470,6 +483,18 @@ export default {
/>
/>
</project-setting-row>
</project-setting-row>
</div>
</div>
<project-setting-row
v-if=
"requirementsAvailable"
ref=
"requirements-settings"
:label=
"s__('ProjectSettings|Requirements')"
:help-text=
"s__('ProjectSettings|Requirements management system for this project')"
>
<project-feature-setting
v-model=
"requirementsAccessLevel"
:options=
"featureAccessLevelOptions"
name=
"project[project_feature_attributes][requirements_access_level]"
/>
</project-setting-row>
<project-setting-row
<project-setting-row
ref=
"wiki-settings"
ref=
"wiki-settings"
:label=
"s__('ProjectSettings|Wiki')"
:label=
"s__('ProjectSettings|Wiki')"
...
...
app/assets/javascripts/pages/projects/shared/permissions/mixins/settings_pannel_mixin.js
View file @
3a770845
...
@@ -2,6 +2,7 @@ export default {
...
@@ -2,6 +2,7 @@ export default {
data
()
{
data
()
{
return
{
return
{
packagesEnabled
:
false
,
packagesEnabled
:
false
,
requirementsEnabled
:
false
,
};
};
},
},
watch
:
{
watch
:
{
...
...
app/controllers/projects_controller.rb
View file @
3a770845
...
@@ -356,6 +356,20 @@ class ProjectsController < Projects::ApplicationController
...
@@ -356,6 +356,20 @@ class ProjectsController < Projects::ApplicationController
.
merge
(
import_url_params
)
.
merge
(
import_url_params
)
end
end
def
project_feature_attributes
%i[
builds_access_level
issues_access_level
forking_access_level
merge_requests_access_level
repository_access_level
snippets_access_level
wiki_access_level
pages_access_level
metrics_dashboard_access_level
]
end
def
project_params_attributes
def
project_params_attributes
[
[
:allow_merge_on_skipped_pipeline
,
:allow_merge_on_skipped_pipeline
,
...
@@ -391,22 +405,10 @@ class ProjectsController < Projects::ApplicationController
...
@@ -391,22 +405,10 @@ class ProjectsController < Projects::ApplicationController
:initialize_with_readme
,
:initialize_with_readme
,
:autoclose_referenced_issues
,
:autoclose_referenced_issues
,
:suggestion_commit_message
,
:suggestion_commit_message
,
project_feature_attributes:
%i[
builds_access_level
issues_access_level
forking_access_level
merge_requests_access_level
repository_access_level
snippets_access_level
wiki_access_level
pages_access_level
metrics_dashboard_access_level
]
,
project_setting_attributes:
%i[
project_setting_attributes:
%i[
show_default_award_emojis
show_default_award_emojis
]
]
]
]
+
[
project_feature_attributes:
project_feature_attributes
]
end
end
def
project_params_create_attributes
def
project_params_create_attributes
...
...
app/models/concerns/featurable.rb
View file @
3a770845
...
@@ -37,7 +37,8 @@ module Featurable
...
@@ -37,7 +37,8 @@ module Featurable
class_methods
do
class_methods
do
def
set_available_features
(
available_features
=
[])
def
set_available_features
(
available_features
=
[])
@available_features
=
available_features
@available_features
||=
[]
@available_features
+=
available_features
class_eval
do
class_eval
do
available_features
.
each
do
|
feature
|
available_features
.
each
do
|
feature
|
...
...
app/models/concerns/project_features_compatibility.rb
View file @
3a770845
...
@@ -88,3 +88,5 @@ module ProjectFeaturesCompatibility
...
@@ -88,3 +88,5 @@ module ProjectFeaturesCompatibility
project_feature
.
__send__
(
:write_attribute
,
field
,
value
)
# rubocop:disable GitlabSecurity/PublicSend
project_feature
.
__send__
(
:write_attribute
,
field
,
value
)
# rubocop:disable GitlabSecurity/PublicSend
end
end
end
end
ProjectsHelper
.
prepend_if_ee
(
'EE::ProjectFeaturesCompatibility'
)
changelogs/unreleased/add_requirements_visibility_access_project_settings.yml
0 → 100644
View file @
3a770845
---
title
:
Add requirements visibility/access project settings
merge_request
:
34420
author
:
Lee Tickett
type
:
added
db/migrate/20200615203153_add_requirements_access_level_to_project_features.rb
0 → 100644
View file @
3a770845
# frozen_string_literal: true
class
AddRequirementsAccessLevelToProjectFeatures
<
ActiveRecord
::
Migration
[
6.0
]
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
def
up
with_lock_retries
do
add_column
:project_features
,
:requirements_access_level
,
:integer
,
default:
20
,
null:
false
end
end
def
down
with_lock_retries
do
remove_column
:project_features
,
:requirements_access_level
,
:integer
end
end
end
db/structure.sql
View file @
3a770845
...
@@ -13956,7 +13956,8 @@ CREATE TABLE public.project_features (
...
@@ -13956,7 +13956,8 @@ CREATE TABLE public.project_features (
repository_access_level
integer
DEFAULT
20
NOT
NULL
,
repository_access_level
integer
DEFAULT
20
NOT
NULL
,
pages_access_level
integer
NOT
NULL
,
pages_access_level
integer
NOT
NULL
,
forking_access_level
integer
,
forking_access_level
integer
,
metrics_dashboard_access_level
integer
metrics_dashboard_access_level
integer
,
requirements_access_level
integer
DEFAULT
20
NOT
NULL
);
);
CREATE
SEQUENCE
public
.
project_features_id_seq
CREATE
SEQUENCE
public
.
project_features_id_seq
...
@@ -23427,6 +23428,7 @@ COPY "schema_migrations" (version) FROM STDIN;
...
@@ -23427,6 +23428,7 @@ COPY "schema_migrations" (version) FROM STDIN;
20200615121217
20200615121217
20200615123055
20200615123055
20200615193524
20200615193524
20200615203153
20200615232735
20200615232735
20200615234047
20200615234047
20200616145031
20200616145031
...
...
doc/api/projects.md
View file @
3a770845
...
@@ -1048,6 +1048,7 @@ POST /projects
...
@@ -1048,6 +1048,7 @@ POST /projects
|
`wiki_access_level`
| string | no | One of
`disabled`
,
`private`
or
`enabled`
|
|
`wiki_access_level`
| string | no | One of
`disabled`
,
`private`
or
`enabled`
|
|
`snippets_access_level`
| string | no | One of
`disabled`
,
`private`
or
`enabled`
|
|
`snippets_access_level`
| string | no | One of
`disabled`
,
`private`
or
`enabled`
|
|
`pages_access_level`
| string | no | One of
`disabled`
,
`private`
,
`enabled`
or
`public`
|
|
`pages_access_level`
| string | no | One of
`disabled`
,
`private`
,
`enabled`
or
`public`
|
|
`requirements_access_level`
| string | no | One of
`disabled`
,
`private`
,
`enabled`
or
`public`
|
|
`emails_disabled`
| boolean | no | Disable email notifications |
|
`emails_disabled`
| boolean | no | Disable email notifications |
|
`show_default_award_emojis`
| boolean | no | Show default award emojis |
|
`show_default_award_emojis`
| boolean | no | Show default award emojis |
|
`resolve_outdated_diff_discussions`
| boolean | no | Automatically resolve merge request diffs discussions on lines changed with a push |
|
`resolve_outdated_diff_discussions`
| boolean | no | Automatically resolve merge request diffs discussions on lines changed with a push |
...
@@ -1119,6 +1120,7 @@ POST /projects/user/:user_id
...
@@ -1119,6 +1120,7 @@ POST /projects/user/:user_id
|
`wiki_access_level`
| string | no | One of
`disabled`
,
`private`
or
`enabled`
|
|
`wiki_access_level`
| string | no | One of
`disabled`
,
`private`
or
`enabled`
|
|
`snippets_access_level`
| string | no | One of
`disabled`
,
`private`
or
`enabled`
|
|
`snippets_access_level`
| string | no | One of
`disabled`
,
`private`
or
`enabled`
|
|
`pages_access_level`
| string | no | One of
`disabled`
,
`private`
,
`enabled`
or
`public`
|
|
`pages_access_level`
| string | no | One of
`disabled`
,
`private`
,
`enabled`
or
`public`
|
|
`requirements_access_level`
| string | no | One of
`disabled`
,
`private`
,
`enabled`
or
`public`
|
|
`emails_disabled`
| boolean | no | Disable email notifications |
|
`emails_disabled`
| boolean | no | Disable email notifications |
|
`show_default_award_emojis`
| boolean | no | Show default award emojis |
|
`show_default_award_emojis`
| boolean | no | Show default award emojis |
|
`resolve_outdated_diff_discussions`
| boolean | no | Automatically resolve merge request diffs discussions on lines changed with a push |
|
`resolve_outdated_diff_discussions`
| boolean | no | Automatically resolve merge request diffs discussions on lines changed with a push |
...
@@ -1189,6 +1191,7 @@ PUT /projects/:id
...
@@ -1189,6 +1191,7 @@ PUT /projects/:id
|
`wiki_access_level`
| string | no | One of
`disabled`
,
`private`
or
`enabled`
|
|
`wiki_access_level`
| string | no | One of
`disabled`
,
`private`
or
`enabled`
|
|
`snippets_access_level`
| string | no | One of
`disabled`
,
`private`
or
`enabled`
|
|
`snippets_access_level`
| string | no | One of
`disabled`
,
`private`
or
`enabled`
|
|
`pages_access_level`
| string | no | One of
`disabled`
,
`private`
,
`enabled`
or
`public`
|
|
`pages_access_level`
| string | no | One of
`disabled`
,
`private`
,
`enabled`
or
`public`
|
|
`requirements_access_level`
| string | no | One of
`disabled`
,
`private`
,
`enabled`
or
`public`
|
|
`emails_disabled`
| boolean | no | Disable email notifications |
|
`emails_disabled`
| boolean | no | Disable email notifications |
|
`show_default_award_emojis`
| boolean | no | Show default award emojis |
|
`show_default_award_emojis`
| boolean | no | Show default award emojis |
|
`resolve_outdated_diff_discussions`
| boolean | no | Automatically resolve merge request diffs discussions on lines changed with a push |
|
`resolve_outdated_diff_discussions`
| boolean | no | Automatically resolve merge request diffs discussions on lines changed with a push |
...
...
doc/user/project/settings/index.md
View file @
3a770845
...
@@ -62,6 +62,7 @@ Use the switches to enable or disable the following features:
...
@@ -62,6 +62,7 @@ Use the switches to enable or disable the following features:
|
**Snippets**
| ✓ | Enables
[
sharing of code and text
](
../../snippets.md
)
|
|
**Snippets**
| ✓ | Enables
[
sharing of code and text
](
../../snippets.md
)
|
|
**Pages**
| ✓ | Allows you to
[
publish static websites
](
../pages/
)
|
|
**Pages**
| ✓ | Allows you to
[
publish static websites
](
../pages/
)
|
|
**Metrics Dashboard**
| ✓ | Control access to
[
metrics dashboard
](
../integrations/prometheus.md
)
|
**Metrics Dashboard**
| ✓ | Control access to
[
metrics dashboard
](
../integrations/prometheus.md
)
|
**Requirements**
| ✓ | Control access to
[
Requirements Management
](
../requirements/index.md
)
Some features depend on others:
Some features depend on others:
...
...
ee/app/assets/javascripts/pages/projects/shared/permissions/mixins/settings_pannel_mixin.js
View file @
3a770845
...
@@ -2,6 +2,7 @@ export default {
...
@@ -2,6 +2,7 @@ export default {
data
()
{
data
()
{
return
{
return
{
packagesEnabled
:
true
,
packagesEnabled
:
true
,
requirementsEnabled
:
true
,
};
};
},
},
watch
:
{
watch
:
{
...
...
ee/app/controllers/ee/projects_controller.rb
View file @
3a770845
...
@@ -49,6 +49,11 @@ module EE
...
@@ -49,6 +49,11 @@ module EE
end
end
end
end
override
:project_feature_attributes
def
project_feature_attributes
super
+
[
:requirements_access_level
]
end
override
:project_params_attributes
override
:project_params_attributes
def
project_params_attributes
def
project_params_attributes
super
+
project_params_ee
super
+
project_params_ee
...
...
ee/app/helpers/ee/projects_helper.rb
View file @
3a770845
...
@@ -53,6 +53,10 @@ module EE
...
@@ -53,6 +53,10 @@ module EE
nav_tabs
<<
:project_insights
nav_tabs
<<
:project_insights
end
end
if
can?
(
current_user
,
:read_requirement
,
project
)
nav_tabs
<<
:requirements
end
nav_tabs
nav_tabs
end
end
...
@@ -66,7 +70,8 @@ module EE
...
@@ -66,7 +70,8 @@ module EE
override
:project_permissions_settings
override
:project_permissions_settings
def
project_permissions_settings
(
project
)
def
project_permissions_settings
(
project
)
super
.
merge
(
super
.
merge
(
packagesEnabled:
!!
project
.
packages_enabled
packagesEnabled:
!!
project
.
packages_enabled
,
requirementsAccessLevel:
project
.
requirements_access_level
)
)
end
end
...
@@ -74,7 +79,8 @@ module EE
...
@@ -74,7 +79,8 @@ module EE
def
project_permissions_panel_data
(
project
)
def
project_permissions_panel_data
(
project
)
super
.
merge
(
super
.
merge
(
packagesAvailable:
::
Gitlab
.
config
.
packages
.
enabled
&&
project
.
feature_available?
(
:packages
),
packagesAvailable:
::
Gitlab
.
config
.
packages
.
enabled
&&
project
.
feature_available?
(
:packages
),
packagesHelpPath:
help_page_path
(
'user/packages/index'
)
packagesHelpPath:
help_page_path
(
'user/packages/index'
),
requirementsAvailable:
project
.
feature_available?
(
:requirements
)
)
)
end
end
...
...
ee/app/models/concerns/ee/project_features_compatibility.rb
0 → 100644
View file @
3a770845
# frozen_string_literal: true
module
EE
module
ProjectFeaturesCompatibility
extend
ActiveSupport
::
Concern
# TODO: remove in API v5, replaced by *_access_level
def
requirements_enabled
=
(
value
)
write_feature_attribute_boolean
(
:requirements_access_level
,
value
)
end
def
requirements_access_level
=
(
value
)
write_feature_attribute_string
(
:requirements_access_level
,
value
)
end
end
end
ee/app/models/ee/project.rb
View file @
3a770845
...
@@ -167,6 +167,8 @@ module EE
...
@@ -167,6 +167,8 @@ module EE
delegate
:merge_trains_enabled?
,
to: :ci_cd_settings
delegate
:merge_trains_enabled?
,
to: :ci_cd_settings
delegate
:closest_gitlab_subscription
,
to: :namespace
delegate
:closest_gitlab_subscription
,
to: :namespace
delegate
:requirements_access_level
,
to: :project_feature
,
allow_nil:
true
validates
:repository_size_limit
,
validates
:repository_size_limit
,
numericality:
{
only_integer:
true
,
greater_than_or_equal_to:
0
,
allow_nil:
true
}
numericality:
{
only_integer:
true
,
greater_than_or_equal_to:
0
,
allow_nil:
true
}
validates
:max_pages_size
,
validates
:max_pages_size
,
...
@@ -184,6 +186,7 @@ module EE
...
@@ -184,6 +186,7 @@ module EE
end
end
default_value_for
:packages_enabled
,
true
default_value_for
:packages_enabled
,
true
default_value_for
:requirements_enabled
,
true
accepts_nested_attributes_for
:tracing_setting
,
update_only:
true
,
allow_destroy:
true
accepts_nested_attributes_for
:tracing_setting
,
update_only:
true
,
allow_destroy:
true
accepts_nested_attributes_for
:status_page_setting
,
update_only:
true
,
allow_destroy:
true
accepts_nested_attributes_for
:status_page_setting
,
update_only:
true
,
allow_destroy:
true
...
...
ee/app/models/ee/project_feature.rb
View file @
3a770845
...
@@ -4,11 +4,17 @@ module EE
...
@@ -4,11 +4,17 @@ module EE
module
ProjectFeature
module
ProjectFeature
extend
ActiveSupport
::
Concern
extend
ActiveSupport
::
Concern
EE_FEATURES
=
%i(requirements)
.
freeze
prepended
do
prepended
do
set_available_features
(
available_features
+
EE_FEATURES
)
# Ensure changes to project visibility settings go to elasticsearch
# Ensure changes to project visibility settings go to elasticsearch
after_commit
on: :update
do
after_commit
on: :update
do
project
.
maintain_elasticsearch_update
if
project
.
maintaining_elasticsearch?
project
.
maintain_elasticsearch_update
if
project
.
maintaining_elasticsearch?
end
end
default_value_for
:requirements_access_level
,
value:
Featurable
::
ENABLED
,
allows_nil:
false
end
end
end
end
end
end
ee/app/policies/ee/project_policy.rb
View file @
3a770845
...
@@ -34,7 +34,7 @@ module EE
...
@@ -34,7 +34,7 @@ module EE
condition
(
:iterations_available
)
{
@subject
.
feature_available?
(
:iterations
)
}
condition
(
:iterations_available
)
{
@subject
.
feature_available?
(
:iterations
)
}
with_scope
:subject
with_scope
:subject
condition
(
:requirements_available
)
{
@subject
.
feature_available?
(
:requirements
)
}
condition
(
:requirements_available
)
{
@subject
.
feature_available?
(
:requirements
)
&
feature_available?
(
:requirements
)
}
condition
(
:compliance_framework_available
)
{
@subject
.
feature_available?
(
:compliance_framework
,
@user
)
}
condition
(
:compliance_framework_available
)
{
@subject
.
feature_available?
(
:compliance_framework
,
@user
)
}
...
...
ee/app/views/layouts/nav/_requirements_link.html.haml
View file @
3a770845
-
return
unless
Feature
.
enabled?
(
:requirements_management
,
project
,
default_enabled:
true
)
-
return
unless
Feature
.
enabled?
(
:requirements_management
,
project
,
default_enabled:
true
)
-
return
unless
can?
(
current_user
,
:read_requirement
,
project
)
-
return
unless
project_nav_tab?
:requirements
=
nav_link
(
path:
'requirements#index'
)
do
=
nav_link
(
path:
'requirements#index'
)
do
=
link_to
project_requirements_management_requirements_path
(
project
),
class:
'qa-project-requirements-link'
do
=
link_to
project_requirements_management_requirements_path
(
project
),
class:
'qa-project-requirements-link'
do
...
...
ee/lib/ee/api/entities/project.rb
View file @
3a770845
...
@@ -31,6 +31,9 @@ module EE
...
@@ -31,6 +31,9 @@ module EE
expose
:marked_for_deletion_on
,
if:
->
(
project
,
_
)
{
project
.
feature_available?
(
:adjourned_deletion_for_projects_and_groups
)
}
do
|
project
,
_
|
expose
:marked_for_deletion_on
,
if:
->
(
project
,
_
)
{
project
.
feature_available?
(
:adjourned_deletion_for_projects_and_groups
)
}
do
|
project
,
_
|
project
.
marked_for_deletion_at
project
.
marked_for_deletion_at
end
end
expose
:requirements_enabled
do
|
project
,
options
|
project
.
feature_available?
(
:requirements
,
options
[
:current_user
])
end
expose
:compliance_frameworks
do
|
project
,
_
|
expose
:compliance_frameworks
do
|
project
,
_
|
[
project
.
compliance_framework_setting
&
.
framework
].
compact
[
project
.
compliance_framework_setting
&
.
framework
].
compact
end
end
...
...
ee/lib/ee/audit/project_feature_changes_auditor.rb
View file @
3a770845
...
@@ -13,7 +13,8 @@ module EE
...
@@ -13,7 +13,8 @@ module EE
:builds_access_level
,
:builds_access_level
,
:repository_access_level
,
:repository_access_level
,
:pages_access_level
,
:pages_access_level
,
:metrics_dashboard_access_level
].
freeze
:metrics_dashboard_access_level
,
:requirements_access_level
].
freeze
def
initialize
(
current_user
,
model
,
project
)
def
initialize
(
current_user
,
model
,
project
)
@project
=
project
@project
=
project
...
...
ee/spec/controllers/projects/requirements_management/requirements_controller_spec.rb
View file @
3a770845
...
@@ -3,33 +3,48 @@
...
@@ -3,33 +3,48 @@
require
'spec_helper'
require
'spec_helper'
RSpec
.
describe
Projects
::
RequirementsManagement
::
RequirementsController
do
RSpec
.
describe
Projects
::
RequirementsManagement
::
RequirementsController
do
let_it_be
(
:project
)
{
create
(
:project
)
}
let_it_be
(
:user
)
{
create
(
:user
)
}
let_it_be
(
:user
)
{
create
(
:user
)
}
subject
{
get
:index
,
params:
{
namespace_id:
project
.
namespace
,
project_id:
project
}
}
subject
{
get
:index
,
params:
{
namespace_id:
project
.
namespace
,
project_id:
project
}
}
describe
'GET #index'
do
describe
'GET #index'
do
context
'with authorized user'
do
context
'private project'
do
before
do
let
(
:project
)
{
create
(
:project
)
}
project
.
add_developer
(
user
)
sign_in
(
user
)
end
context
'w
hen feature is available
'
do
context
'w
ith authorized user
'
do
before
do
before
do
stub_licensed_features
(
requirements:
true
)
project
.
add_developer
(
user
)
sign_in
(
user
)
end
end
it
'renders the index template'
do
context
'when feature is available'
do
subject
before
do
stub_licensed_features
(
requirements:
true
)
end
it
'renders the index template'
do
subject
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
response
).
to
render_template
(
:index
)
expect
(
response
).
to
render_template
(
:index
)
end
context
'when requirements_management flag is disabled'
do
before
do
stub_feature_flags
(
requirements_management:
false
)
end
it
'returns 404'
do
subject
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
end
end
end
end
context
'when
requirements_management flag is disabled
'
do
context
'when
feature is not available
'
do
before
do
before
do
stub_
feature_flags
(
requirements_management
:
false
)
stub_
licensed_features
(
requirements
:
false
)
end
end
it
'returns 404'
do
it
'returns 404'
do
...
@@ -40,27 +55,46 @@ RSpec.describe Projects::RequirementsManagement::RequirementsController do
...
@@ -40,27 +55,46 @@ RSpec.describe Projects::RequirementsManagement::RequirementsController do
end
end
end
end
context
'w
hen feature is not available
'
do
context
'w
ith unauthorized user
'
do
before
do
before
do
s
tub_licensed_features
(
requirements:
false
)
s
ign_in
(
user
)
end
end
it
'returns 404'
do
context
'when feature is available'
do
before
do
stub_licensed_features
(
requirements:
true
)
end
it
'returns 404'
do
subject
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
end
end
end
context
'with anonymous user'
do
it
'returns 302'
do
subject
subject
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
expect
(
response
).
to
have_gitlab_http_status
(
:found
)
expect
(
response
).
to
redirect_to
(
new_user_session_path
)
end
end
end
end
end
end
context
'with unauthorized user'
do
context
'public project'
do
let
(
:project
)
{
create
(
:project
,
:public
)
}
before
do
before
do
s
ign_in
(
user
)
s
tub_licensed_features
(
requirements:
true
)
end
end
context
'w
hen feature is available
'
do
context
'w
ith requirements disabled
'
do
before
do
before
do
stub_licensed_features
(
requirements:
true
)
project
.
project_feature
.
update!
({
requirements_access_level:
::
ProjectFeature
::
DISABLED
})
project
.
add_developer
(
user
)
sign_in
(
user
)
end
end
it
'returns 404'
do
it
'returns 404'
do
...
@@ -69,14 +103,52 @@ RSpec.describe Projects::RequirementsManagement::RequirementsController do
...
@@ -69,14 +103,52 @@ RSpec.describe Projects::RequirementsManagement::RequirementsController do
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
end
end
end
end
end
context
'with anonymous user'
do
context
'with requirements visible to project memebers'
do
it
'returns 302'
do
before
do
subject
project
.
project_feature
.
update!
({
requirements_access_level:
::
ProjectFeature
::
PRIVATE
})
end
context
'with authorized user'
do
before
do
project
.
add_developer
(
user
)
sign_in
(
user
)
end
it
'renders the index template'
do
subject
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
response
).
to
render_template
(
:index
)
end
end
expect
(
response
).
to
have_gitlab_http_status
(
:found
)
context
'with unauthorized user'
do
expect
(
response
).
to
redirect_to
(
new_user_session_path
)
before
do
sign_in
(
user
)
end
it
'returns 404'
do
subject
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
end
end
end
context
'with requirements visible to everyone'
do
before
do
project
.
project_feature
.
update!
({
requirements_access_level:
::
ProjectFeature
::
ENABLED
})
end
context
'with anonymous user'
do
it
'renders the index template'
do
subject
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
response
).
to
render_template
(
:index
)
end
end
end
end
end
end
end
end
...
...
ee/spec/factories/projects.rb
View file @
3a770845
...
@@ -76,6 +76,10 @@ FactoryBot.modify do
...
@@ -76,6 +76,10 @@ FactoryBot.modify do
service_desk_enabled
{
true
}
service_desk_enabled
{
true
}
end
end
trait
(
:issues_enabled
)
do
issues_access_level
{
ProjectFeature
::
ENABLED
}
end
trait
:github_imported
do
trait
:github_imported
do
import_type
{
'github'
}
import_type
{
'github'
}
end
end
...
...
ee/spec/support/shared_examples/policies/requirement_policy_shared_examples.rb
View file @
3a770845
# frozen_string_literal: true
# frozen_string_literal: true
RSpec
.
shared_examples
'resource with requirement permissions'
do
RSpec
.
shared_examples
'resource with requirement permissions'
do
include
AdminModeHelper
let
(
:all_permissions
)
do
let
(
:all_permissions
)
do
[
:read_requirement
,
:create_requirement
,
:admin_requirement
,
[
:read_requirement
,
:create_requirement
,
:admin_requirement
,
:update_requirement
,
:destroy_requirement
,
:update_requirement
,
:destroy_requirement
,
...
@@ -77,6 +79,82 @@ RSpec.shared_examples 'resource with requirement permissions' do
...
@@ -77,6 +79,82 @@ RSpec.shared_examples 'resource with requirement permissions' do
it
{
is_expected
.
to
be_disallowed
(
*
all_permissions
)
}
it
{
is_expected
.
to
be_disallowed
(
*
all_permissions
)
}
end
end
end
end
context
'when access level is disabled'
do
before
do
parent
=
resource
.
is_a?
(
Project
)
?
resource
:
resource
.
resource_parent
parent
.
project_feature
.
update!
(
requirements_access_level:
ProjectFeature
::
DISABLED
)
end
context
'with owner'
do
let
(
:current_user
)
{
owner
}
it
{
is_expected
.
to
be_disallowed
(
*
all_permissions
)
}
end
context
'with admin'
do
let
(
:current_user
)
{
admin
}
it
{
is_expected
.
to
be_disallowed
(
*
all_permissions
)
}
end
end
context
'when access level is private'
do
before
do
parent
=
resource
.
is_a?
(
Project
)
?
resource
:
resource
.
resource_parent
parent
.
project_feature
.
update!
(
requirements_access_level:
ProjectFeature
::
PRIVATE
)
end
context
'with admin'
do
let
(
:current_user
)
{
admin
}
it
{
is_expected
.
to
be_disallowed
(
*
all_permissions
)
}
context
'with '
do
before
do
enable_admin_mode!
(
current_user
)
end
it_behaves_like
'user with read only permissions'
end
end
context
'with owner'
do
let
(
:current_user
)
{
owner
}
it
{
is_expected
.
to
be_allowed
(
*
all_permissions
)
}
end
context
'with maintainer'
do
let
(
:current_user
)
{
maintainer
}
it_behaves_like
'user with manage permissions'
end
context
'with developer'
do
let
(
:current_user
)
{
developer
}
it_behaves_like
'user with manage permissions'
end
context
'with reporter'
do
let
(
:current_user
)
{
reporter
}
it_behaves_like
'user with manage permissions'
end
context
'with guest'
do
let
(
:current_user
)
{
guest
}
it_behaves_like
'user with read only permissions'
end
context
'with non member'
do
let
(
:current_user
)
{
create
(
:user
)
}
it
{
is_expected
.
to
be_disallowed
(
*
all_permissions
)
}
end
end
end
end
context
'when requirements feature is disabled'
do
context
'when requirements feature is disabled'
do
...
...
locale/gitlab.pot
View file @
3a770845
...
@@ -17782,6 +17782,12 @@ msgstr ""
...
@@ -17782,6 +17782,12 @@ msgstr ""
msgid "ProjectSettings|Repository"
msgid "ProjectSettings|Repository"
msgstr ""
msgstr ""
msgid "ProjectSettings|Requirements"
msgstr ""
msgid "ProjectSettings|Requirements management system for this project"
msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr ""
msgstr ""
...
...
spec/lib/gitlab/import_export/safe_model_attributes.yml
View file @
3a770845
...
@@ -533,6 +533,7 @@ Project:
...
@@ -533,6 +533,7 @@ Project:
-
merge_requests_enabled
-
merge_requests_enabled
-
wiki_enabled
-
wiki_enabled
-
snippets_enabled
-
snippets_enabled
-
requirements_enabled
-
visibility_level
-
visibility_level
-
archived
-
archived
-
created_at
-
created_at
...
@@ -600,6 +601,7 @@ ProjectFeature:
...
@@ -600,6 +601,7 @@ ProjectFeature:
-
repository_access_level
-
repository_access_level
-
pages_access_level
-
pages_access_level
-
metrics_dashboard_access_level
-
metrics_dashboard_access_level
-
requirements_access_level
-
created_at
-
created_at
-
updated_at
-
updated_at
ProtectedBranch::MergeAccessLevel:
ProtectedBranch::MergeAccessLevel:
...
...
spec/policies/project_policy_spec.rb
View file @
3a770845
...
@@ -80,6 +80,7 @@ RSpec.describe ProjectPolicy do
...
@@ -80,6 +80,7 @@ RSpec.describe ProjectPolicy do
let
(
:additional_guest_permissions
)
{
[]
}
let
(
:additional_guest_permissions
)
{
[]
}
let
(
:additional_reporter_permissions
)
{
[]
}
let
(
:additional_reporter_permissions
)
{
[]
}
let
(
:additional_maintainer_permissions
)
{
[]
}
let
(
:additional_maintainer_permissions
)
{
[]
}
let
(
:additional_owner_permissions
)
{
[]
}
let
(
:guest_permissions
)
{
base_guest_permissions
+
additional_guest_permissions
}
let
(
:guest_permissions
)
{
base_guest_permissions
+
additional_guest_permissions
}
let
(
:reporter_permissions
)
{
base_reporter_permissions
+
additional_reporter_permissions
}
let
(
:reporter_permissions
)
{
base_reporter_permissions
+
additional_reporter_permissions
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment