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
0
Merge Requests
0
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
Jérome Perrin
gitlab-ce
Commits
37c40143
Commit
37c40143
authored
Apr 06, 2017
by
http://jneen.net/
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
convert all the policies to DeclarativePolicy
parent
e5aad75a
Changes
30
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
30 changed files
with
629 additions
and
662 deletions
+629
-662
app/models/ability.rb
app/models/ability.rb
+16
-14
app/models/project_feature.rb
app/models/project_feature.rb
+5
-2
app/policies/base_policy.rb
app/policies/base_policy.rb
+9
-123
app/policies/ci/build_policy.rb
app/policies/ci/build_policy.rb
+6
-22
app/policies/ci/pipeline_policy.rb
app/policies/ci/pipeline_policy.rb
+1
-3
app/policies/ci/runner_policy.rb
app/policies/ci/runner_policy.rb
+9
-6
app/policies/ci/trigger_policy.rb
app/policies/ci/trigger_policy.rb
+12
-9
app/policies/commit_status_policy.rb
app/policies/commit_status_policy.rb
+4
-2
app/policies/deploy_key_policy.rb
app/policies/deploy_key_policy.rb
+7
-7
app/policies/deployment_policy.rb
app/policies/deployment_policy.rb
+1
-3
app/policies/environment_policy.rb
app/policies/environment_policy.rb
+4
-12
app/policies/external_issue_policy.rb
app/policies/external_issue_policy.rb
+1
-3
app/policies/global_policy.rb
app/policies/global_policy.rb
+35
-11
app/policies/group_label_policy.rb
app/policies/group_label_policy.rb
+1
-3
app/policies/group_member_policy.rb
app/policies/group_member_policy.rb
+13
-16
app/policies/group_policy.rb
app/policies/group_policy.rb
+52
-44
app/policies/issuable_policy.rb
app/policies/issuable_policy.rb
+10
-9
app/policies/issue_policy.rb
app/policies/issue_policy.rb
+9
-17
app/policies/namespace_policy.rb
app/policies/namespace_policy.rb
+6
-6
app/policies/nil_policy.rb
app/policies/nil_policy.rb
+3
-0
app/policies/note_policy.rb
app/policies/note_policy.rb
+18
-13
app/policies/personal_snippet_policy.rb
app/policies/personal_snippet_policy.rb
+21
-20
app/policies/project_label_policy.rb
app/policies/project_label_policy.rb
+1
-3
app/policies/project_member_policy.rb
app/policies/project_member_policy.rb
+10
-16
app/policies/project_policy.rb
app/policies/project_policy.rb
+315
-259
app/policies/project_snippet_policy.rb
app/policies/project_snippet_policy.rb
+42
-22
app/policies/user_policy.rb
app/policies/user_policy.rb
+13
-12
lib/gitlab/allowable.rb
lib/gitlab/allowable.rb
+2
-2
spec/policies/project_policy_spec.rb
spec/policies/project_policy_spec.rb
+2
-2
spec/policies/project_snippet_policy_spec.rb
spec/policies/project_snippet_policy_spec.rb
+1
-1
No files found.
app/models/ability.rb
View file @
37c40143
...
...
@@ -56,24 +56,26 @@ class Ability
end
end
def
allowed?
(
user
,
action
,
subject
=
:global
)
allowed
(
user
,
subject
).
include?
(
action
)
def
allowed?
(
user
,
action
,
subject
=
:global
,
opts
=
{})
if
subject
.
is_a?
(
Hash
)
opts
,
subject
=
subject
,
:global
end
def
allowed
(
user
,
subject
=
:global
)
return
BasePolicy
::
RuleSet
.
none
if
subject
.
nil?
return
uncached_allowed
(
user
,
subject
)
unless
RequestStore
.
active?
policy
=
policy_for
(
user
,
subject
)
user_key
=
user
?
user
.
id
:
'anonymous'
subject_key
=
subject
==
:global
?
'global'
:
"
#{
subject
.
class
.
name
}
/
#{
subject
.
id
}
"
key
=
"/ability/
#{
user_key
}
/
#{
subject_key
}
"
RequestStore
[
key
]
||=
uncached_allowed
(
user
,
subject
).
freeze
case
opts
[
:scope
]
when
:user
DeclarativePolicy
.
user_scope
{
policy
.
can?
(
action
)
}
when
:subject
DeclarativePolicy
.
subject_scope
{
policy
.
can?
(
action
)
}
else
policy
.
can?
(
action
)
end
end
private
def
uncached_allowed
(
user
,
subject
)
BasePolicy
.
class_for
(
subject
).
abilities
(
user
,
subject
)
def
policy_for
(
user
,
subject
=
:global
)
cache
=
RequestStore
.
active?
?
RequestStore
:
{}
DeclarativePolicy
.
policy_for
(
user
,
subject
,
cache:
cache
)
end
end
end
app/models/project_feature.rb
View file @
37c40143
...
...
@@ -51,8 +51,11 @@ class ProjectFeature < ActiveRecord::Base
default_value_for
:repository_access_level
,
value:
ENABLED
,
allows_nil:
false
def
feature_available?
(
feature
,
user
)
access_level
=
public_send
(
ProjectFeature
.
access_level_attribute
(
feature
))
get_permission
(
user
,
access_level
)
get_permission
(
user
,
access_level
(
feature
))
end
def
access_level
(
feature
)
public_send
(
ProjectFeature
.
access_level_attribute
(
feature
))
end
def
builds_enabled?
...
...
app/policies/base_policy.rb
View file @
37c40143
class
BasePolicy
class
RuleSet
attr_reader
:can_set
,
:cannot_set
def
initialize
(
can_set
,
cannot_set
)
@can_set
=
can_set
@cannot_set
=
cannot_set
end
require
'declarative_policy'
delegate
:size
,
to: :to_set
class
BasePolicy
<
DeclarativePolicy
::
Base
desc
"User is an instance admin"
with_options
scope: :user
,
score:
0
condition
(
:admin
)
{
@user
&
.
admin?
}
def
self
.
empty
new
(
Set
.
new
,
Set
.
new
)
end
with_options
scope: :user
,
score:
0
condition
(
:external_user
)
{
@user
.
nil?
||
@user
.
external?
}
def
self
.
none
empty
.
freeze
end
def
can?
(
ability
)
@can_set
.
include?
(
ability
)
&&
!
@cannot_set
.
include?
(
ability
)
end
def
include?
(
ability
)
can?
(
ability
)
end
def
to_set
@can_set
-
@cannot_set
end
def
merge
(
other
)
@can_set
.
merge
(
other
.
can_set
)
@cannot_set
.
merge
(
other
.
cannot_set
)
end
def
can!
(
*
abilities
)
@can_set
.
merge
(
abilities
)
end
def
cannot!
(
*
abilities
)
@cannot_set
.
merge
(
abilities
)
end
def
freeze
@can_set
.
freeze
@cannot_set
.
freeze
super
end
end
def
self
.
abilities
(
user
,
subject
)
new
(
user
,
subject
).
abilities
end
def
self
.
class_for
(
subject
)
return
GlobalPolicy
if
subject
==
:global
raise
ArgumentError
,
'no policy for nil'
if
subject
.
nil?
if
subject
.
class
.
try
(
:presenter?
)
subject
=
subject
.
subject
end
subject
.
class
.
ancestors
.
each
do
|
klass
|
next
unless
klass
.
name
begin
policy_class
=
"
#{
klass
.
name
}
Policy"
.
constantize
# NOTE: the < operator here tests whether policy_class
# inherits from BasePolicy
return
policy_class
if
policy_class
<
BasePolicy
rescue
NameError
nil
end
end
raise
"no policy for
#{
subject
.
class
.
name
}
"
end
attr_reader
:user
,
:subject
def
initialize
(
user
,
subject
)
@user
=
user
@subject
=
subject
end
def
abilities
return
RuleSet
.
none
if
@user
&&
@user
.
blocked?
return
anonymous_abilities
if
@user
.
nil?
collect_rules
{
rules
}
end
def
anonymous_abilities
collect_rules
{
anonymous_rules
}
end
def
anonymous_rules
rules
end
def
rules
raise
NotImplementedError
end
def
delegate!
(
new_subject
)
@rule_set
.
merge
(
Ability
.
allowed
(
@user
,
new_subject
))
end
def
can?
(
rule
)
@rule_set
.
can?
(
rule
)
end
def
can!
(
*
rules
)
@rule_set
.
can!
(
*
rules
)
end
def
cannot!
(
*
rules
)
@rule_set
.
cannot!
(
*
rules
)
end
private
def
collect_rules
(
&
b
)
@rule_set
=
RuleSet
.
empty
yield
@rule_set
end
with_options
scope: :user
,
score:
0
condition
(
:can_create_group
)
{
@user
&
.
can_create_group
}
end
app/policies/ci/build_policy.rb
View file @
37c40143
module
Ci
class
BuildPolicy
<
CommitStatusPolicy
alias_method
:build
,
:subject
def
rules
super
# If we can't read build we should also not have that
# ability when looking at this in context of commit_status
%w[read create update admin]
.
each
do
|
rule
|
cannot!
:"
#{
rule
}
_commit_status"
unless
can?
:"
#{
rule
}
_build"
end
if
can?
(
:update_build
)
&&
protected_action?
cannot!
:update_build
end
end
private
def
protected_action?
return
false
unless
build
.
action?
condition
(
:protected_action
)
do
next
false
unless
@subject
.
action?
!::
Gitlab
::
UserAccess
.
new
(
user
,
project:
build
.
project
)
.
can_merge_to_branch?
(
build
.
ref
)
.
new
(
@user
,
project:
@subject
.
project
)
.
can_merge_to_branch?
(
@subject
.
ref
)
end
rule
{
protected_action
}.
prevent
:update_build
end
end
app/policies/ci/pipeline_policy.rb
View file @
37c40143
module
Ci
class
PipelinePolicy
<
BasePolicy
def
rules
delegate!
@subject
.
project
end
delegate
{
@subject
.
project
}
end
end
app/policies/ci/runner_policy.rb
View file @
37c40143
module
Ci
class
RunnerPolicy
<
BasePolicy
def
rules
return
unless
@user
with_options
scope: :subject
,
score:
0
condition
(
:shared
)
{
@subject
.
is_shared?
}
can!
:assign_runner
if
@user
.
admin?
with_options
scope: :subject
,
score:
0
condition
(
:locked
,
scope: :subject
)
{
@subject
.
locked?
}
return
if
@subject
.
is_shared?
||
@subject
.
locked?
condition
(
:authorized_runner
)
{
@user
.
ci_authorized_runners
.
include?
(
@subject
)
}
can!
:assign_runner
if
@user
.
ci_authorized_runners
.
include?
(
@subject
)
end
rule
{
anonymous
}.
prevent_all
rule
{
admin
|
authorized_runner
}.
enable
:assign_runner
rule
{
~
admin
&
shared
}.
prevent
:assign_runner
rule
{
~
admin
&
locked
}.
prevent
:assign_runner
end
end
app/policies/ci/trigger_policy.rb
View file @
37c40143
module
Ci
class
TriggerPolicy
<
BasePolicy
def
rules
delegate!
@subject
.
project
delegate
{
@subject
.
project
}
if
can?
(
:admin_build
)
can!
:admin_trigger
if
@subject
.
owner
.
blank?
||
@subject
.
owner
==
@user
can!
:manage_trigger
end
end
with_options
scope: :subject
,
score:
0
condition
(
:legacy
)
{
@subject
.
legacy?
}
with_score
0
condition
(
:is_owner
)
{
@user
&&
@subject
.
owner_id
==
@user
.
id
}
rule
{
~
can?
(
:admin_build
)
}.
prevent
:admin_trigger
rule
{
legacy
|
is_owner
}.
enable
:admin_trigger
rule
{
can?
(
:admin_build
)
}.
enable
:manage_trigger
end
end
app/policies/commit_status_policy.rb
View file @
37c40143
class
CommitStatusPolicy
<
BasePolicy
def
rules
delegate!
@subject
.
project
delegate
{
@subject
.
project
}
%w[read create update admin]
.
each
do
|
action
|
rule
{
~
can?
(
:"
#{
action
}
_commit_status"
)
}.
prevent
:"
#{
action
}
_build"
end
end
app/policies/deploy_key_policy.rb
View file @
37c40143
class
DeployKeyPolicy
<
BasePolicy
def
rules
return
unless
@user
with_options
scope: :subject
,
score:
0
condition
(
:private_deploy_key
)
{
@subject
.
private?
}
can!
:update_deploy_key
if
@user
.
admin?
condition
(
:has_deploy_key
)
{
@user
.
project_deploy_keys
.
exists?
(
id:
@subject
.
id
)
}
if
@subject
.
private?
&&
@user
.
project_deploy_keys
.
exists?
(
id:
@subject
.
id
)
can!
:update_deploy_key
end
end
rule
{
anonymous
}.
prevent_all
rule
{
admin
}.
enable
:update_deploy_key
rule
{
private_deploy_key
&
has_deploy_key
}.
enable
:update_deploy_key
end
app/policies/deployment_policy.rb
View file @
37c40143
class
DeploymentPolicy
<
BasePolicy
def
rules
delegate!
@subject
.
project
end
delegate
{
@subject
.
project
}
end
app/policies/environment_policy.rb
View file @
37c40143
class
EnvironmentPolicy
<
BasePolicy
alias_method
:environment
,
:subject
delegate
{
@subject
.
project
}
def
rules
delegate!
environment
.
project
if
can?
(
:create_deployment
)
&&
environment
.
stop_action?
can!
:stop_environment
if
can_play_stop_action?
end
condition
(
:stop_action_allowed
)
do
@subject
.
stop_action?
&&
can?
(
:update_build
,
@subject
.
stop_action
)
end
private
def
can_play_stop_action?
Ability
.
allowed?
(
user
,
:update_build
,
environment
.
stop_action
)
end
rule
{
can?
(
:create_deployment
)
&
stop_action_allowed
}.
enable
:stop_environment
end
app/policies/external_issue_policy.rb
View file @
37c40143
class
ExternalIssuePolicy
<
BasePolicy
def
rules
delegate!
@subject
.
project
end
delegate
{
@subject
.
project
}
end
app/policies/global_policy.rb
View file @
37c40143
class
GlobalPolicy
<
BasePolicy
def
rules
return
unless
@user
desc
"User is blocked"
with_options
scope: :user
,
score:
0
condition
(
:blocked
)
{
@user
.
blocked?
}
can!
:create_group
if
@user
.
can_create_group
can!
:read_users_list
desc
"User is an internal user"
with_options
scope: :user
,
score:
0
condition
(
:internal
)
{
@user
.
internal?
}
unless
@user
.
blocked?
||
@user
.
internal?
can!
:log_in
unless
@user
.
access_locked?
can!
:access_api
can!
:access_git
can!
:receive_notifications
can!
:use_quick_actions
desc
"User's access has been locked"
with_options
scope: :user
,
score:
0
condition
(
:access_locked
)
{
@user
.
access_locked?
}
rule
{
anonymous
}.
prevent_all
rule
{
default
}.
policy
do
enable
:read_users_list
enable
:log_in
enable
:access_api
enable
:access_git
enable
:receive_notifications
enable
:use_quick_actions
end
rule
{
blocked
|
internal
}.
policy
do
prevent
:log_in
prevent
:access_api
prevent
:access_git
prevent
:receive_notifications
prevent
:use_quick_actions
end
rule
{
can_create_group
}.
policy
do
enable
:create_group
end
rule
{
access_locked
}.
policy
do
prevent
:log_in
end
end
app/policies/group_label_policy.rb
View file @
37c40143
class
GroupLabelPolicy
<
BasePolicy
def
rules
delegate!
@subject
.
group
end
delegate
{
@subject
.
group
}
end
app/policies/group_member_policy.rb
View file @
37c40143
class
GroupMemberPolicy
<
BasePolicy
def
rules
return
unless
@user
delegate
:group
target_user
=
@subject
.
user
group
=
@subject
.
group
with_scope
:subject
condition
(
:last_owner
)
{
@subject
.
group
.
last_owner?
(
@subject
.
user
)
}
return
if
group
.
last_owner?
(
target_user
)
desc
"Membership is users' own"
with_score
0
condition
(
:is_target_user
)
{
@user
&&
@subject
.
user_id
==
@user
.
id
}
can_manage
=
Ability
.
allowed?
(
@user
,
:admin_group_member
,
group
)
rule
{
anonymous
}.
prevent_all
rule
{
last_owner
}.
prevent_all
if
can_manage
can!
:update_group_member
can!
:destroy_group_member
elsif
@user
==
target_user
can!
:destroy_group_member
rule
{
can?
(
:admin_group_member
)
}.
policy
do
enable
:update_group_member
enable
:destroy_group_member
end
additional_rules!
end
def
additional_rules!
# This is meant to be overriden in EE
rule
{
is_target_user
}.
policy
do
enable
:destroy_group_member
end
end
app/policies/group_policy.rb
View file @
37c40143
class
GroupPolicy
<
BasePolicy
def
rules
can!
:read_group
if
@subject
.
public?
return
unless
@user
globally_viewable
=
@subject
.
public?
||
(
@subject
.
internal?
&&
!
@user
.
external?
)
access_level
=
@subject
.
max_member_access_for_user
(
@user
)
owner
=
access_level
>=
GroupMember
::
OWNER
master
=
access_level
>=
GroupMember
::
MASTER
reporter
=
access_level
>=
GroupMember
::
REPORTER
can_read
=
false
can_read
||=
globally_viewable
can_read
||=
access_level
>=
GroupMember
::
GUEST
can_read
||=
GroupProjectsFinder
.
new
(
group:
@subject
,
current_user:
@user
).
execute
.
any?
can!
:read_group
if
can_read
if
reporter
can!
:admin_label
end
desc
"Group is public"
with_options
scope: :subject
,
score:
0
condition
(
:public_group
)
{
@subject
.
public?
}
# Only group masters and group owners can create new projects
if
master
can!
:create_projects
can!
:admin_milestones
end
with_score
0
condition
(
:logged_in_viewable
)
{
@user
&&
@subject
.
internal?
&&
!
@user
.
external?
}
condition
(
:has_access
)
{
access_level
!=
GroupMember
::
NO_ACCESS
}
condition
(
:guest
)
{
access_level
>=
GroupMember
::
GUEST
}
condition
(
:owner
)
{
access_level
>=
GroupMember
::
OWNER
}
condition
(
:master
)
{
access_level
>=
GroupMember
::
MASTER
}
condition
(
:reporter
)
{
access_level
>=
GroupMember
::
REPORTER
}
# Only group owner and administrators can admin group
if
owner
can!
:admin_group
can!
:admin_namespace
can!
:admin_group_member
can!
:change_visibility_level
can!
:create_subgroup
if
@user
.
can_create_group
condition
(
:has_projects
)
do
GroupProjectsFinder
.
new
(
group:
@subject
,
current_user:
@user
).
execute
.
any?
end
if
globally_viewable
&&
@subject
.
request_access_enabled
&&
access_level
==
GroupMember
::
NO_ACCESS
can!
:request_access
with_options
scope: :subject
,
score:
0
condition
(
:request_access_enabled
)
{
@subject
.
request_access_enabled
}
rule
{
public_group
}
.
enable
:read_group
rule
{
logged_in_viewable
}.
enable
:read_group
rule
{
guest
}
.
enable
:read_group
rule
{
admin
}
.
enable
:read_group
rule
{
has_projects
}
.
enable
:read_group
rule
{
reporter
}.
enable
:admin_label
rule
{
master
}.
policy
do
enable
:create_projects
enable
:admin_milestones
end
rule
{
owner
}.
policy
do
enable
:admin_group
enable
:admin_namespace
enable
:admin_group_member
enable
:change_visibility_level
end
def
can_read_group?
return
true
if
@subject
.
public?
return
true
if
@user
.
admin?
return
true
if
@subject
.
internal?
&&
!
@user
.
external?
return
true
if
@subject
.
users
.
include?
(
@user
)
rule
{
owner
&
can_create_group
}.
enable
:create_subgroup
GroupProjectsFinder
.
new
(
group:
@subject
,
current_user:
@user
).
execute
.
any?
rule
{
public_group
|
logged_in_viewable
}.
enable
:view_globally
rule
{
default
}.
enable
(
:request_access
)
rule
{
~
request_access_enabled
}.
prevent
:request_access
rule
{
~
can?
(
:view_globally
)
}.
prevent
:request_access
rule
{
has_access
}.
prevent
:request_access
def
access_level
return
GroupMember
::
NO_ACCESS
if
@user
.
nil?
@access_level
||=
@subject
.
max_member_access_for_user
(
@user
)
end
end
app/policies/issuable_policy.rb
View file @
37c40143
class
IssuablePolicy
<
BasePolicy
def
action_name
@subject
.
class
.
name
.
underscore
end
delegate
{
@subject
.
project
}
def
rules
if
@user
&&
@subject
.
assignee_or_author?
(
@user
)
can!
:"read_
#{
action_name
}
"
can!
:"update_
#{
action_name
}
"
desc
"User is the assignee or author"
condition
(
:assignee_or_author
)
do
@user
&&
@subject
.
assignee_or_author?
(
@user
)
end
delegate!
@subject
.
project
rule
{
assignee_or_author
}.
policy
do
enable
:read_issue
enable
:update_issue
enable
:read_merge_request
enable
:update_merge_request
end
end
app/policies/issue_policy.rb
View file @
37c40143
...
...
@@ -3,25 +3,17 @@ class IssuePolicy < IssuablePolicy
# Make sure to sync this class checks with issue.rb to avoid security problems.
# Check commit 002ad215818450d2cbbc5fa065850a953dc7ada8 for more information.
def
issue
@subject
desc
"User can read confidential issues"
condition
(
:can_read_confidential
)
do
@user
&&
IssueCollection
.
new
([
@subject
]).
visible_to
(
@user
).
any?
end
de
f
rules
super
de
sc
"Issue is confidential"
condition
(
:confidential
,
scope: :subject
)
{
@subject
.
confidential?
}
if
@subject
.
confidential?
&&
!
can_read_confidential?
cannot!
:read_issue
cannot!
:update_issue
cannot!
:admin_issue
end
end
private
def
can_read_confidential?
return
false
unless
@user
IssueCollection
.
new
([
@subject
]).
visible_to
(
@user
).
any?
rule
{
confidential
&
~
can_read_confidential
}.
policy
do
prevent
:read_issue
prevent
:update_issue
prevent
:admin_issue
end
end
app/policies/namespace_policy.rb
View file @
37c40143
class
NamespacePolicy
<
BasePolicy
def
rules
return
unless
@user
rule
{
anonymous
}.
prevent_all
if
@subject
.
owner
==
@user
||
@user
.
admin?
can!
:create_projects
can!
:admin_namespace
end
condition
(
:owner
)
{
@subject
.
owner
==
@user
}
rule
{
owner
|
admin
}.
policy
do
enable
:create_projects
enable
:admin_namespace
end
end
app/policies/nil_policy.rb
0 → 100644
View file @
37c40143
class
NilPolicy
<
BasePolicy
rule
{
default
}.
prevent_all
end
app/policies/note_policy.rb
View file @
37c40143
class
NotePolicy
<
BasePolicy
def
rules
delegate!
@subject
.
project
delegate
{
@subject
.
project
}
return
unless
@user
condition
(
:is_author
)
{
@user
&&
@subject
.
author
==
@user
}
condition
(
:for_merge_request
,
scope: :subject
)
{
@subject
.
for_merge_request?
}
condition
(
:is_noteable_author
)
{
@user
&&
@subject
.
noteable
.
author_id
==
@user
.
id
}
if
@subject
.
author
==
@user
can!
:read_note
can!
:update_note
can!
:admin_note
can!
:resolve_note
end
condition
(
:editable
,
scope: :subject
)
{
@subject
.
editable?
}
rule
{
~
editable
|
anonymous
}.
prevent
:edit_note
rule
{
is_author
|
admin
}.
enable
:edit_note
rule
{
can?
(
:master_access
)
}.
enable
:edit_note
if
@subject
.
for_merge_request?
&&
@subject
.
noteable
.
author
==
@user
can!
:resolve_note
rule
{
is_author
}.
policy
do
enable
:read_note
enable
:update_note
enable
:admin_note
enable
:resolve_note
end
rule
{
for_merge_request
&
is_noteable_author
}.
policy
do
enable
:resolve_note
end
end
app/policies/personal_snippet_policy.rb
View file @
37c40143
class
PersonalSnippetPolicy
<
BasePolicy
def
rules
can!
:read_personal_snippet
if
@subject
.
public?
return
unless
@user
condition
(
:public_snippet
,
scope: :subject
)
{
@subject
.
public?
}
condition
(
:is_author
)
{
@user
&&
@subject
.
author
==
@user
}
condition
(
:internal_snippet
,
scope: :subject
)
{
@subject
.
internal?
}
if
@subject
.
public?
can!
:comment_personal_snippet
rule
{
public_snippet
}.
policy
do
enable
:read_personal_snippet
enable
:comment_personal_snippet
end
if
@subject
.
author
==
@user
can!
:read_personal_snippet
can!
:update_personal_snippet
can!
:destroy_personal_snippet
can!
:admin_personal_snippet
can!
:comment_personal_snippet
rule
{
is_author
}.
policy
do
enable
:read_personal_snippet
enable
:update_personal_snippet
enable
:destroy_personal_snippet
enable
:admin_personal_snippet
enable
:comment_personal_snippet
end
unless
@user
.
external?
can!
:create_personal_snippet
end
rule
{
~
anonymous
}.
enable
:create_personal_snippet
rule
{
external_user
}.
prevent
:create_personal_snippet
if
@subject
.
internal?
&&
!
@user
.
external?
can!
:read_personal_snippet
can!
:comment_personal_snippet
end
rule
{
internal_snippet
&
~
external_user
}.
policy
do
enable
:read_personal_snippet
enable
:comment_personal_snippet
end
rule
{
anonymous
}.
prevent
:comment_personal_snippet
end
app/policies/project_label_policy.rb
View file @
37c40143
class
ProjectLabelPolicy
<
BasePolicy
def
rules
delegate!
@subject
.
project
end
delegate
{
@subject
.
project
}
end
app/policies/project_member_policy.rb
View file @
37c40143
class
ProjectMemberPolicy
<
BasePolicy
def
rules
# anonymous users have no abilities here
return
unless
@user
delegate
{
@subject
.
project
}
target_user
=
@subject
.
user
project
=
@subject
.
project
condition
(
:target_is_owner
,
scope: :subject
)
{
@subject
.
user
==
@subject
.
project
.
owner
}
condition
(
:target_is_self
)
{
@user
&&
@subject
.
user
==
@user
}
return
if
target_user
==
project
.
owner
rule
{
anonymous
}.
prevent_all
rule
{
target_is_owner
}.
prevent_all
can_manage
=
Ability
.
allowed?
(
@user
,
:admin_project_member
,
project
)
if
can_manage
can!
:update_project_member
can!
:destroy_project_member
rule
{
can?
(
:admin_project_member
)
}.
policy
do
enable
:update_project_member
enable
:destroy_project_member
end
if
@user
==
target_user
can!
:destroy_project_member
end
end
rule
{
target_is_self
}.
enable
:destroy_project_member
end
app/policies/project_policy.rb
View file @
37c40143
This diff is collapsed.
Click to expand it.
app/policies/project_snippet_policy.rb
View file @
37c40143
class
ProjectSnippetPolicy
<
BasePolicy
def
rules
delegate
:project
desc
"Snippet is public"
condition
(
:public_snippet
,
scope: :subject
)
{
@subject
.
public?
}
condition
(
:private_snippet
,
scope: :subject
)
{
@subject
.
private?
}
condition
(
:public_project
,
scope: :subject
)
{
@subject
.
project
.
public?
}
condition
(
:is_author
)
{
@user
&&
@subject
.
author
==
@user
}
condition
(
:internal
,
scope: :subject
)
{
@subject
.
internal?
}
# We have to check both project feature visibility and a snippet visibility and take the stricter one
# This will be simplified - check https://gitlab.com/gitlab-org/gitlab-ce/issues/27573
return
unless
@subject
.
project
.
feature_available?
(
:snippets
,
@user
)
return
unless
Ability
.
allowed?
(
@user
,
:read_project
,
@subject
.
project
)
rule
{
~
can?
(
:read_project
)
}.
policy
do
prevent
:read_project_snippet
prevent
:update_project_snippet
prevent
:admin_project_snippet
end
can!
:read_project_snippet
if
@subject
.
public?
return
unless
@user
# we have to use this complicated prevent because the delegated project policy
# is overly greedy in allowing :read_project_snippet, since it doesn't have any
# information about the snippet. However, :read_project_snippet on the *project*
# is used to hide/show various snippet-related controls, so we can't just move
# all of the handling here.
rule
do
all?
(
private_snippet
|
(
internal
&
external_user
),
~
project
.
guest
,
~
admin
,
~
is_author
)
end
.
prevent
:read_project_snippet
if
@user
&&
(
@subject
.
author
==
@user
||
@user
.
admin?
)
can!
:read_project_snippet
can!
:update_project_snippet
can!
:admin_project_snippet
rule
{
internal
&
~
is_author
&
~
admin
}.
policy
do
prevent
:update_project_snippet
prevent
:admin_project_snippet
end
if
@subject
.
internal?
&&
!
@user
.
external?
can!
:read_project_snippet
end
rule
{
public_snippet
}.
enable
:read_project_snippet
if
@subject
.
project
.
team
.
member?
(
@user
)
can!
:read_project_snippet
end
rule
{
is_author
|
admin
}.
policy
do
enable
:read_project_snippet
enable
:update_project_snippet
enable
:admin_project_snippet
end
end
app/policies/user_policy.rb
View file @
37c40143
class
UserPolicy
<
BasePolicy
include
Gitlab
::
CurrentSettings
def
rules
can!
:read_user
if
@user
||
!
restricted_public_level?
if
@user
if
@user
.
admin?
||
@subject
==
@user
can!
:destroy_user
desc
"The application is restricted from public visibility"
condition
(
:restricted_public_level
,
scope: :global
)
do
current_application_settings
.
restricted_visibility_levels
.
include?
(
Gitlab
::
VisibilityLevel
::
PUBLIC
)
end
cannot!
:destroy_user
if
@subject
.
ghost?
end
end
desc
"The current user is the user in question"
condition
(
:user_is_self
,
score:
0
)
{
@subject
==
@user
}
def
restricted_public_level?
current_application_settings
.
restricted_visibility_levels
.
include?
(
Gitlab
::
VisibilityLevel
::
PUBLIC
)
end
desc
"This is the ghost user"
condition
(
:subject_ghost
,
scope: :subject
,
score:
0
)
{
@subject
.
ghost?
}
rule
{
~
restricted_public_level
}.
enable
:read_user
rule
{
~
anonymous
}.
enable
:read_user
rule
{
user_is_self
|
admin
}.
enable
:destroy_user
rule
{
subject_ghost
}.
prevent
:destroy_user
end
lib/gitlab/allowable.rb
View file @
37c40143
module
Gitlab
module
Allowable
def
can?
(
user
,
action
,
subject
=
:global
)
Ability
.
allowed?
(
user
,
action
,
subject
)
def
can?
(
*
args
)
Ability
.
allowed?
(
*
args
)
end
end
end
spec/policies/project_policy_spec.rb
View file @
37c40143
...
...
@@ -155,8 +155,8 @@ describe ProjectPolicy, models: true do
end
it
do
is_expected
.
not_to
include
(
:read_build
)
is_expected
.
to
include
(
:read_pipeline
)
expect_disallowed
(
:read_build
)
expect_allowed
(
:read_pipeline
)
end
end
end
...
...
spec/policies/project_snippet_policy_spec.rb
View file @
37c40143
...
...
@@ -119,7 +119,7 @@ describe ProjectSnippetPolicy, models: true do
context
'snippet author'
do
let
(
:snippet
)
{
create
(
:project_snippet
,
:private
,
author:
regular_user
,
project:
project
)
}
subject
{
described_class
(
regular_user
,
snippet
)
}
subject
{
described_class
.
new
(
regular_user
,
snippet
)
}
it
do
expect_allowed
(
:read_project_snippet
)
...
...
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