2011-10-08 17:36:38 -04:00
|
|
|
class Ability
|
2012-10-08 20:10:04 -04:00
|
|
|
class << self
|
2016-06-30 09:38:29 -04:00
|
|
|
# rubocop: disable Metrics/CyclomaticComplexity
|
2013-01-25 04:30:49 -05:00
|
|
|
def allowed(user, subject)
|
2015-11-17 15:00:14 -05:00
|
|
|
return anonymous_abilities(user, subject) if user.nil?
|
2015-11-17 10:24:02 -05:00
|
|
|
return [] unless user.is_a?(User)
|
2013-08-27 05:41:49 -04:00
|
|
|
return [] if user.blocked?
|
2013-01-25 04:30:49 -05:00
|
|
|
|
2016-02-04 08:43:52 -05:00
|
|
|
case subject
|
|
|
|
when CommitStatus then commit_status_abilities(user, subject)
|
|
|
|
when Project then project_abilities(user, subject)
|
|
|
|
when Issue then issue_abilities(user, subject)
|
|
|
|
when Note then note_abilities(user, subject)
|
|
|
|
when ProjectSnippet then project_snippet_abilities(user, subject)
|
|
|
|
when PersonalSnippet then personal_snippet_abilities(user, subject)
|
|
|
|
when MergeRequest then merge_request_abilities(user, subject)
|
|
|
|
when Group then group_abilities(user, subject)
|
|
|
|
when Namespace then namespace_abilities(user, subject)
|
|
|
|
when GroupMember then group_member_abilities(user, subject)
|
|
|
|
when ProjectMember then project_member_abilities(user, subject)
|
2016-03-30 16:14:21 -04:00
|
|
|
when User then user_abilities
|
2016-06-15 06:12:26 -04:00
|
|
|
when ExternalIssue, Deployment, Environment then project_abilities(user, subject.project)
|
2016-06-29 07:04:06 -04:00
|
|
|
when Ci::Runner then runner_abilities(user, subject)
|
2015-11-12 03:43:30 -05:00
|
|
|
else []
|
2013-01-25 04:30:49 -05:00
|
|
|
end.concat(global_abilities(user))
|
|
|
|
end
|
|
|
|
|
2016-05-26 07:38:28 -04:00
|
|
|
# Given a list of users and a project this method returns the users that can
|
|
|
|
# read the given project.
|
|
|
|
def users_that_can_read_project(users, project)
|
|
|
|
if project.public?
|
|
|
|
users
|
|
|
|
else
|
|
|
|
users.select do |user|
|
|
|
|
if user.admin?
|
|
|
|
true
|
|
|
|
elsif project.internal? && !user.external?
|
|
|
|
true
|
|
|
|
elsif project.owner == user
|
|
|
|
true
|
|
|
|
elsif project.team.members.include?(user)
|
|
|
|
true
|
|
|
|
else
|
|
|
|
false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-11-17 15:00:14 -05:00
|
|
|
# List of possible abilities for anonymous user
|
|
|
|
def anonymous_abilities(user, subject)
|
2016-05-30 06:34:25 -04:00
|
|
|
if subject.is_a?(PersonalSnippet)
|
2015-11-17 15:00:14 -05:00
|
|
|
anonymous_personal_snippet_abilities(subject)
|
2016-05-30 06:34:25 -04:00
|
|
|
elsif subject.is_a?(ProjectSnippet)
|
2016-03-25 07:31:43 -04:00
|
|
|
anonymous_project_snippet_abilities(subject)
|
2016-05-30 06:34:25 -04:00
|
|
|
elsif subject.is_a?(CommitStatus)
|
2016-02-04 05:09:42 -05:00
|
|
|
anonymous_commit_status_abilities(subject)
|
2016-05-30 06:34:25 -04:00
|
|
|
elsif subject.is_a?(Project) || subject.respond_to?(:project)
|
2015-11-17 15:00:14 -05:00
|
|
|
anonymous_project_abilities(subject)
|
2016-05-30 06:34:25 -04:00
|
|
|
elsif subject.is_a?(Group) || subject.respond_to?(:group)
|
2015-11-17 15:00:14 -05:00
|
|
|
anonymous_group_abilities(subject)
|
2016-05-30 06:34:25 -04:00
|
|
|
elsif subject.is_a?(User)
|
2016-03-30 16:14:21 -04:00
|
|
|
anonymous_user_abilities
|
2015-11-17 10:24:02 -05:00
|
|
|
else
|
|
|
|
[]
|
|
|
|
end
|
2015-10-29 16:42:29 -04:00
|
|
|
end
|
|
|
|
|
2015-11-17 15:00:14 -05:00
|
|
|
def anonymous_project_abilities(subject)
|
2015-11-17 10:24:02 -05:00
|
|
|
project = if subject.is_a?(Project)
|
2013-09-24 08:58:39 -04:00
|
|
|
subject
|
|
|
|
else
|
2015-10-29 16:42:29 -04:00
|
|
|
subject.project
|
2013-09-24 08:58:39 -04:00
|
|
|
end
|
|
|
|
|
2013-11-06 10:13:21 -05:00
|
|
|
if project && project.public?
|
2015-07-19 17:21:33 -04:00
|
|
|
rules = [
|
2013-09-24 15:13:28 -04:00
|
|
|
:read_project,
|
|
|
|
:read_wiki,
|
2015-07-19 14:58:59 -04:00
|
|
|
:read_label,
|
2013-09-24 15:13:28 -04:00
|
|
|
:read_milestone,
|
|
|
|
:read_project_snippet,
|
2015-03-13 11:22:03 -04:00
|
|
|
:read_project_member,
|
2013-09-24 15:13:28 -04:00
|
|
|
:read_merge_request,
|
|
|
|
:read_note,
|
2016-05-21 18:58:11 -04:00
|
|
|
:read_pipeline,
|
2016-02-01 17:58:04 -05:00
|
|
|
:read_commit_status,
|
2016-05-14 19:23:31 -04:00
|
|
|
:read_container_image,
|
2013-09-24 15:13:28 -04:00
|
|
|
:download_code
|
|
|
|
]
|
2015-07-19 17:21:33 -04:00
|
|
|
|
2016-02-04 05:09:42 -05:00
|
|
|
# Allow to read builds by anonymous user if guests are allowed
|
2016-02-04 06:57:46 -05:00
|
|
|
rules << :read_build if project.public_builds?
|
2016-02-01 17:58:04 -05:00
|
|
|
|
2016-03-17 15:38:51 -04:00
|
|
|
# Allow to read issues by anonymous user if issue is not confidential
|
|
|
|
rules << :read_issue unless subject.is_a?(Issue) && subject.confidential?
|
|
|
|
|
2015-07-19 17:21:33 -04:00
|
|
|
rules - project_disabled_features_rules(project)
|
2013-09-24 08:58:39 -04:00
|
|
|
else
|
2015-10-29 16:42:29 -04:00
|
|
|
[]
|
|
|
|
end
|
|
|
|
end
|
2014-02-25 07:36:36 -05:00
|
|
|
|
2016-02-04 05:09:42 -05:00
|
|
|
def anonymous_commit_status_abilities(subject)
|
|
|
|
rules = anonymous_project_abilities(subject.project)
|
|
|
|
# If subject is Ci::Build which inherits from CommitStatus filter the abilities
|
|
|
|
rules = filter_build_abilities(rules) if subject.is_a?(Ci::Build)
|
|
|
|
rules
|
|
|
|
end
|
|
|
|
|
2015-11-17 15:00:14 -05:00
|
|
|
def anonymous_group_abilities(subject)
|
2016-03-29 11:24:42 -04:00
|
|
|
rules = []
|
|
|
|
|
2015-11-17 10:24:02 -05:00
|
|
|
group = if subject.is_a?(Group)
|
2015-10-29 16:42:29 -04:00
|
|
|
subject
|
|
|
|
else
|
|
|
|
subject.group
|
|
|
|
end
|
|
|
|
|
2016-04-07 15:36:26 -04:00
|
|
|
rules << :read_group if group.public?
|
2016-03-29 11:24:42 -04:00
|
|
|
|
|
|
|
rules
|
2015-10-29 16:42:29 -04:00
|
|
|
end
|
|
|
|
|
2015-11-17 15:00:14 -05:00
|
|
|
def anonymous_personal_snippet_abilities(snippet)
|
2015-10-29 16:42:29 -04:00
|
|
|
if snippet.public?
|
|
|
|
[:read_personal_snippet]
|
|
|
|
else
|
|
|
|
[]
|
2013-09-24 08:58:39 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-03-25 07:31:43 -04:00
|
|
|
def anonymous_project_snippet_abilities(snippet)
|
|
|
|
if snippet.public?
|
|
|
|
[:read_project_snippet]
|
|
|
|
else
|
|
|
|
[]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-03-30 16:14:21 -04:00
|
|
|
def anonymous_user_abilities
|
|
|
|
[:read_user] unless restricted_public_level?
|
2016-03-29 11:24:42 -04:00
|
|
|
end
|
|
|
|
|
2013-01-25 04:30:49 -05:00
|
|
|
def global_abilities(user)
|
|
|
|
rules = []
|
|
|
|
rules << :create_group if user.can_create_group
|
2016-04-12 11:04:33 -04:00
|
|
|
rules << :read_users_list
|
2013-01-25 04:30:49 -05:00
|
|
|
rules
|
2011-10-08 17:36:38 -04:00
|
|
|
end
|
|
|
|
|
2012-10-08 20:10:04 -04:00
|
|
|
def project_abilities(user, project)
|
|
|
|
rules = []
|
2014-06-14 06:05:25 -04:00
|
|
|
key = "/user/#{user.id}/project/#{project.id}"
|
2015-06-26 12:15:36 -04:00
|
|
|
|
2014-06-14 06:05:25 -04:00
|
|
|
RequestStore.store[key] ||= begin
|
2016-03-10 16:08:11 -05:00
|
|
|
# Push abilities on the users team role
|
2016-04-18 12:53:32 -04:00
|
|
|
rules.push(*project_team_rules(project.team, user))
|
2011-10-08 17:36:38 -04:00
|
|
|
|
2016-07-05 10:58:27 -04:00
|
|
|
owner = user.admin? ||
|
|
|
|
project.owner == user ||
|
|
|
|
(project.group && project.group.has_owner?(user))
|
2016-03-20 16:03:53 -04:00
|
|
|
|
2016-07-05 08:24:58 -04:00
|
|
|
if owner
|
2016-03-20 16:03:53 -04:00
|
|
|
rules.push(*project_owner_rules)
|
|
|
|
end
|
|
|
|
|
2016-03-10 16:08:11 -05:00
|
|
|
if project.public? || (project.internal? && !user.external?)
|
2014-10-09 03:47:47 -04:00
|
|
|
rules.push(*public_project_rules)
|
2016-02-01 17:58:04 -05:00
|
|
|
|
2016-02-04 08:43:52 -05:00
|
|
|
# Allow to read builds for internal projects
|
2016-02-04 06:57:46 -05:00
|
|
|
rules << :read_build if project.public_builds?
|
2016-07-05 08:24:58 -04:00
|
|
|
|
2016-07-05 12:55:35 -04:00
|
|
|
unless owner || project.team.member?(user) || project_group_member?(project, user)
|
|
|
|
rules << :request_access
|
|
|
|
end
|
2014-06-14 06:05:25 -04:00
|
|
|
end
|
2012-11-28 23:29:11 -05:00
|
|
|
|
2014-06-14 06:05:25 -04:00
|
|
|
if project.archived?
|
|
|
|
rules -= project_archived_rules
|
|
|
|
end
|
2013-06-17 07:17:32 -04:00
|
|
|
|
2015-07-19 17:21:33 -04:00
|
|
|
rules - project_disabled_features_rules(project)
|
2013-11-29 11:10:59 -05:00
|
|
|
end
|
2012-11-28 23:29:11 -05:00
|
|
|
end
|
|
|
|
|
2016-03-10 16:08:11 -05:00
|
|
|
def project_team_rules(team, user)
|
|
|
|
# Rules based on role in project
|
|
|
|
if team.master?(user)
|
|
|
|
project_master_rules
|
|
|
|
elsif team.developer?(user)
|
|
|
|
project_dev_rules
|
|
|
|
elsif team.reporter?(user)
|
|
|
|
project_report_rules
|
|
|
|
elsif team.guest?(user)
|
|
|
|
project_guest_rules
|
2016-04-18 12:53:32 -04:00
|
|
|
else
|
|
|
|
[]
|
2016-03-10 16:08:11 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-06-06 07:16:08 -04:00
|
|
|
def public_project_rules
|
2015-12-15 22:51:37 -05:00
|
|
|
@public_project_rules ||= project_guest_rules + [
|
2013-06-06 07:16:08 -04:00
|
|
|
:download_code,
|
2016-02-01 17:58:04 -05:00
|
|
|
:fork_project,
|
2016-06-21 04:11:07 -04:00
|
|
|
:read_commit_status,
|
|
|
|
:read_pipeline
|
2013-06-06 07:16:08 -04:00
|
|
|
]
|
|
|
|
end
|
|
|
|
|
2012-11-28 23:29:11 -05:00
|
|
|
def project_guest_rules
|
2015-12-15 22:51:37 -05:00
|
|
|
@project_guest_rules ||= [
|
2012-10-08 20:10:04 -04:00
|
|
|
:read_project,
|
|
|
|
:read_wiki,
|
|
|
|
:read_issue,
|
2015-06-17 10:33:51 -04:00
|
|
|
:read_label,
|
2012-10-08 20:10:04 -04:00
|
|
|
:read_milestone,
|
2013-03-25 03:20:14 -04:00
|
|
|
:read_project_snippet,
|
2015-03-13 11:22:03 -04:00
|
|
|
:read_project_member,
|
2012-10-08 20:10:04 -04:00
|
|
|
:read_merge_request,
|
|
|
|
:read_note,
|
2015-06-26 09:55:56 -04:00
|
|
|
:create_project,
|
|
|
|
:create_issue,
|
2016-03-21 19:09:20 -04:00
|
|
|
:create_note,
|
|
|
|
:upload_file
|
2012-11-28 23:29:11 -05:00
|
|
|
]
|
|
|
|
end
|
2012-02-20 13:16:55 -05:00
|
|
|
|
2012-11-28 23:29:11 -05:00
|
|
|
def project_report_rules
|
2015-12-15 22:51:37 -05:00
|
|
|
@project_report_rules ||= project_guest_rules + [
|
2012-10-08 20:10:04 -04:00
|
|
|
:download_code,
|
2013-06-04 11:50:42 -04:00
|
|
|
:fork_project,
|
2015-06-30 07:33:02 -04:00
|
|
|
:create_project_snippet,
|
|
|
|
:update_issue,
|
|
|
|
:admin_issue,
|
2016-02-01 17:58:04 -05:00
|
|
|
:admin_label,
|
2016-02-04 06:57:46 -05:00
|
|
|
:read_commit_status,
|
2016-02-01 17:58:04 -05:00
|
|
|
:read_build,
|
2016-05-14 19:23:31 -04:00
|
|
|
:read_container_image,
|
2016-04-12 10:16:39 -04:00
|
|
|
:read_pipeline,
|
2016-06-10 17:36:54 -04:00
|
|
|
:read_environment,
|
|
|
|
:read_deployment
|
2012-11-28 23:29:11 -05:00
|
|
|
]
|
|
|
|
end
|
2012-02-20 13:16:55 -05:00
|
|
|
|
2012-11-28 23:29:11 -05:00
|
|
|
def project_dev_rules
|
2015-12-15 22:51:37 -05:00
|
|
|
@project_dev_rules ||= project_report_rules + [
|
2015-07-23 14:48:55 -04:00
|
|
|
:admin_merge_request,
|
2016-03-04 15:52:52 -05:00
|
|
|
:update_merge_request,
|
2016-02-01 17:58:04 -05:00
|
|
|
:create_commit_status,
|
|
|
|
:update_commit_status,
|
|
|
|
:create_build,
|
|
|
|
:update_build,
|
2016-04-12 10:16:39 -04:00
|
|
|
:create_pipeline,
|
|
|
|
:update_pipeline,
|
2015-06-26 09:55:56 -04:00
|
|
|
:create_merge_request,
|
|
|
|
:create_wiki,
|
2016-04-18 08:13:16 -04:00
|
|
|
:push_code,
|
2016-05-14 19:23:31 -04:00
|
|
|
:create_container_image,
|
|
|
|
:update_container_image,
|
2016-06-10 17:36:54 -04:00
|
|
|
:create_environment,
|
2016-06-15 06:56:02 -04:00
|
|
|
:create_deployment
|
2012-11-28 23:29:11 -05:00
|
|
|
]
|
|
|
|
end
|
2012-10-21 05:12:14 -04:00
|
|
|
|
2013-11-29 11:10:59 -05:00
|
|
|
def project_archived_rules
|
2015-12-15 22:51:37 -05:00
|
|
|
@project_archived_rules ||= [
|
2015-06-26 09:55:56 -04:00
|
|
|
:create_merge_request,
|
2013-11-29 11:10:59 -05:00
|
|
|
:push_code,
|
|
|
|
:push_code_to_protected_branches,
|
2015-06-26 09:55:56 -04:00
|
|
|
:update_merge_request,
|
2013-11-29 11:10:59 -05:00
|
|
|
:admin_merge_request
|
|
|
|
]
|
|
|
|
end
|
|
|
|
|
2012-11-28 23:29:11 -05:00
|
|
|
def project_master_rules
|
2015-12-15 22:51:37 -05:00
|
|
|
@project_master_rules ||= project_dev_rules + [
|
2012-11-28 23:29:11 -05:00
|
|
|
:push_code_to_protected_branches,
|
2015-06-26 09:55:56 -04:00
|
|
|
:update_project_snippet,
|
2016-06-14 12:34:48 -04:00
|
|
|
:update_environment,
|
2016-06-15 06:56:02 -04:00
|
|
|
:update_deployment,
|
2012-10-08 20:10:04 -04:00
|
|
|
:admin_milestone,
|
2013-03-25 03:20:14 -04:00
|
|
|
:admin_project_snippet,
|
2015-03-13 11:22:03 -04:00
|
|
|
:admin_project_member,
|
2012-10-08 20:10:04 -04:00
|
|
|
:admin_merge_request,
|
|
|
|
:admin_note,
|
2012-12-04 15:06:55 -05:00
|
|
|
:admin_wiki,
|
2016-02-01 17:58:04 -05:00
|
|
|
:admin_project,
|
|
|
|
:admin_commit_status,
|
2016-04-12 10:16:39 -04:00
|
|
|
:admin_build,
|
2016-05-14 19:23:31 -04:00
|
|
|
:admin_container_image,
|
2016-06-10 17:36:54 -04:00
|
|
|
:admin_pipeline,
|
|
|
|
:admin_environment,
|
|
|
|
:admin_deployment
|
2012-11-28 23:29:11 -05:00
|
|
|
]
|
|
|
|
end
|
2011-10-08 17:36:38 -04:00
|
|
|
|
2016-03-20 16:03:53 -04:00
|
|
|
def project_owner_rules
|
|
|
|
@project_owner_rules ||= project_master_rules + [
|
2012-12-04 15:06:55 -05:00
|
|
|
:change_namespace,
|
2013-11-06 10:13:21 -05:00
|
|
|
:change_visibility_level,
|
2012-12-04 15:48:24 -05:00
|
|
|
:rename_project,
|
2013-11-29 11:10:59 -05:00
|
|
|
:remove_project,
|
2015-10-13 06:24:44 -04:00
|
|
|
:archive_project,
|
2016-03-14 16:46:44 -04:00
|
|
|
:remove_fork_project,
|
2016-03-21 09:12:52 -04:00
|
|
|
:destroy_merge_request,
|
|
|
|
:destroy_issue
|
2012-11-28 23:29:11 -05:00
|
|
|
]
|
2012-10-08 20:10:04 -04:00
|
|
|
end
|
2011-10-17 06:39:03 -04:00
|
|
|
|
2015-07-19 17:21:33 -04:00
|
|
|
def project_disabled_features_rules(project)
|
|
|
|
rules = []
|
|
|
|
|
|
|
|
unless project.issues_enabled
|
|
|
|
rules += named_abilities('issue')
|
|
|
|
end
|
|
|
|
|
|
|
|
unless project.merge_requests_enabled
|
|
|
|
rules += named_abilities('merge_request')
|
|
|
|
end
|
|
|
|
|
|
|
|
unless project.issues_enabled or project.merge_requests_enabled
|
|
|
|
rules += named_abilities('label')
|
|
|
|
rules += named_abilities('milestone')
|
|
|
|
end
|
|
|
|
|
|
|
|
unless project.snippets_enabled
|
|
|
|
rules += named_abilities('project_snippet')
|
|
|
|
end
|
|
|
|
|
|
|
|
unless project.wiki_enabled
|
|
|
|
rules += named_abilities('wiki')
|
|
|
|
end
|
|
|
|
|
2016-02-01 17:58:04 -05:00
|
|
|
unless project.builds_enabled
|
|
|
|
rules += named_abilities('build')
|
2016-04-12 10:16:39 -04:00
|
|
|
rules += named_abilities('pipeline')
|
2016-06-10 17:36:54 -04:00
|
|
|
rules += named_abilities('environment')
|
|
|
|
rules += named_abilities('deployment')
|
2016-02-01 17:58:04 -05:00
|
|
|
end
|
|
|
|
|
2016-05-09 13:29:57 -04:00
|
|
|
unless project.container_registry_enabled
|
2016-05-14 19:23:31 -04:00
|
|
|
rules += named_abilities('container_image')
|
2016-05-09 13:29:57 -04:00
|
|
|
end
|
|
|
|
|
2015-07-19 17:21:33 -04:00
|
|
|
rules
|
|
|
|
end
|
|
|
|
|
2014-09-25 18:07:40 -04:00
|
|
|
def group_abilities(user, group)
|
2012-11-24 15:00:30 -05:00
|
|
|
rules = []
|
2016-03-02 17:13:50 -05:00
|
|
|
rules << :read_group if can_read_group?(user, group)
|
2013-09-11 14:00:16 -04:00
|
|
|
|
2016-07-05 10:58:27 -04:00
|
|
|
owner = user.admin? || group.has_owner?(user)
|
|
|
|
master = owner || group.has_master?(user)
|
2016-07-05 08:24:58 -04:00
|
|
|
|
2016-03-20 16:03:53 -04:00
|
|
|
# Only group masters and group owners can create new projects
|
2016-07-05 08:24:58 -04:00
|
|
|
if master
|
2015-11-17 09:40:54 -05:00
|
|
|
rules += [
|
2014-05-28 12:03:01 -04:00
|
|
|
:create_projects,
|
2016-03-02 17:13:50 -05:00
|
|
|
:admin_milestones
|
2015-11-17 09:40:54 -05:00
|
|
|
]
|
2014-05-28 12:03:01 -04:00
|
|
|
end
|
|
|
|
|
2015-04-10 08:39:10 -04:00
|
|
|
# Only group owner and administrators can admin group
|
2016-07-05 08:24:58 -04:00
|
|
|
if owner
|
2015-11-17 09:49:37 -05:00
|
|
|
rules += [
|
|
|
|
:admin_group,
|
|
|
|
:admin_namespace,
|
2016-03-02 17:13:50 -05:00
|
|
|
:admin_group_member,
|
|
|
|
:change_visibility_level
|
2015-11-17 09:49:37 -05:00
|
|
|
]
|
2013-01-02 11:57:02 -05:00
|
|
|
end
|
2012-11-24 15:00:30 -05:00
|
|
|
|
2016-07-05 10:58:27 -04:00
|
|
|
if group.public? || (group.internal? && !user.external?)
|
2016-07-05 08:24:58 -04:00
|
|
|
rules << :request_access unless group.users.include?(user)
|
|
|
|
end
|
|
|
|
|
2012-11-24 15:00:30 -05:00
|
|
|
rules.flatten
|
|
|
|
end
|
|
|
|
|
2016-03-02 17:13:50 -05:00
|
|
|
def can_read_group?(user, group)
|
2016-03-21 19:09:20 -04:00
|
|
|
return true if user.admin?
|
|
|
|
return true if group.public?
|
|
|
|
return true if group.internal? && !user.external?
|
|
|
|
return true if group.users.include?(user)
|
|
|
|
|
|
|
|
GroupProjectsFinder.new(group).execute(user).any?
|
2016-03-02 17:13:50 -05:00
|
|
|
end
|
|
|
|
|
2014-09-25 18:07:40 -04:00
|
|
|
def namespace_abilities(user, namespace)
|
2013-06-21 15:44:40 -04:00
|
|
|
rules = []
|
|
|
|
|
2015-04-10 08:39:10 -04:00
|
|
|
# Only namespace owner and administrators can admin it
|
2013-06-21 15:44:40 -04:00
|
|
|
if namespace.owner == user || user.admin?
|
2015-11-17 09:49:37 -05:00
|
|
|
rules += [
|
|
|
|
:create_projects,
|
|
|
|
:admin_namespace
|
|
|
|
]
|
2013-06-21 15:44:40 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
rules.flatten
|
|
|
|
end
|
|
|
|
|
2015-06-26 12:15:36 -04:00
|
|
|
[:issue, :merge_request].each do |name|
|
2011-10-17 06:39:03 -04:00
|
|
|
define_method "#{name}_abilities" do |user, subject|
|
2015-06-26 12:15:36 -04:00
|
|
|
rules = []
|
|
|
|
|
|
|
|
if subject.author == user || (subject.respond_to?(:assignee) && subject.assignee == user)
|
|
|
|
rules += [
|
2011-10-17 06:39:03 -04:00
|
|
|
:"read_#{name}",
|
2015-06-26 11:18:40 -04:00
|
|
|
:"update_#{name}",
|
2011-10-17 06:39:03 -04:00
|
|
|
]
|
2015-06-26 12:15:36 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
rules += project_abilities(user, subject.project)
|
2016-03-17 15:38:51 -04:00
|
|
|
rules = filter_confidential_issues_abilities(user, subject, rules) if subject.is_a?(Issue)
|
2015-06-26 12:15:36 -04:00
|
|
|
rules
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-03-25 13:51:17 -04:00
|
|
|
def note_abilities(user, note)
|
|
|
|
rules = []
|
2015-06-26 12:15:36 -04:00
|
|
|
|
2016-03-25 13:51:17 -04:00
|
|
|
if note.author == user
|
|
|
|
rules += [
|
|
|
|
:read_note,
|
|
|
|
:update_note,
|
|
|
|
:admin_note
|
|
|
|
]
|
|
|
|
end
|
2015-06-26 12:15:36 -04:00
|
|
|
|
2016-03-25 13:51:17 -04:00
|
|
|
if note.respond_to?(:project) && note.project
|
|
|
|
rules += project_abilities(user, note.project)
|
2011-10-17 06:39:03 -04:00
|
|
|
end
|
2016-03-25 13:51:17 -04:00
|
|
|
|
|
|
|
rules
|
2011-10-17 06:39:03 -04:00
|
|
|
end
|
2014-02-07 11:59:55 -05:00
|
|
|
|
2015-10-29 16:42:29 -04:00
|
|
|
def personal_snippet_abilities(user, snippet)
|
|
|
|
rules = []
|
|
|
|
|
|
|
|
if snippet.author == user
|
|
|
|
rules += [
|
|
|
|
:read_personal_snippet,
|
|
|
|
:update_personal_snippet,
|
|
|
|
:admin_personal_snippet
|
|
|
|
]
|
|
|
|
end
|
|
|
|
|
2016-03-10 16:08:11 -05:00
|
|
|
if snippet.public? || (snippet.internal? && !user.external?)
|
2015-12-15 22:51:37 -05:00
|
|
|
rules << :read_personal_snippet
|
2015-10-29 16:42:29 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
rules
|
|
|
|
end
|
|
|
|
|
2016-03-25 13:51:17 -04:00
|
|
|
def project_snippet_abilities(user, snippet)
|
|
|
|
rules = []
|
|
|
|
|
|
|
|
if snippet.author == user || user.admin?
|
|
|
|
rules += [
|
|
|
|
:read_project_snippet,
|
|
|
|
:update_project_snippet,
|
|
|
|
:admin_project_snippet
|
|
|
|
]
|
|
|
|
end
|
|
|
|
|
|
|
|
if snippet.public? || (snippet.internal? && !user.external?) || (snippet.private? && snippet.project.team.member?(user))
|
|
|
|
rules << :read_project_snippet
|
|
|
|
end
|
|
|
|
|
|
|
|
rules
|
|
|
|
end
|
|
|
|
|
2015-03-13 11:16:51 -04:00
|
|
|
def group_member_abilities(user, subject)
|
2014-02-07 11:59:55 -05:00
|
|
|
rules = []
|
|
|
|
target_user = subject.user
|
|
|
|
group = subject.group
|
2015-06-26 12:15:36 -04:00
|
|
|
|
2015-11-17 09:49:37 -05:00
|
|
|
unless group.last_owner?(target_user)
|
|
|
|
can_manage = group_abilities(user, group).include?(:admin_group_member)
|
2015-06-26 12:15:36 -04:00
|
|
|
|
2015-12-01 16:45:58 -05:00
|
|
|
if can_manage
|
2015-11-17 09:49:37 -05:00
|
|
|
rules << :update_group_member
|
|
|
|
rules << :destroy_group_member
|
2015-12-01 16:45:58 -05:00
|
|
|
elsif user == target_user
|
2015-11-17 09:49:37 -05:00
|
|
|
rules << :destroy_group_member
|
|
|
|
end
|
2014-02-07 11:59:55 -05:00
|
|
|
end
|
2015-06-26 12:15:36 -04:00
|
|
|
|
2014-02-07 11:59:55 -05:00
|
|
|
rules
|
|
|
|
end
|
2014-10-19 04:50:23 -04:00
|
|
|
|
2015-11-03 06:11:56 -05:00
|
|
|
def project_member_abilities(user, subject)
|
|
|
|
rules = []
|
|
|
|
target_user = subject.user
|
|
|
|
project = subject.project
|
|
|
|
|
2016-07-05 12:55:35 -04:00
|
|
|
unless target_user == project.owner
|
2015-11-17 09:49:37 -05:00
|
|
|
can_manage = project_abilities(user, project).include?(:admin_project_member)
|
2015-11-03 06:11:56 -05:00
|
|
|
|
2015-12-01 17:47:26 -05:00
|
|
|
if can_manage
|
2015-11-17 09:49:37 -05:00
|
|
|
rules << :update_project_member
|
|
|
|
rules << :destroy_project_member
|
2015-12-01 17:47:26 -05:00
|
|
|
elsif user == target_user
|
2015-11-17 09:49:37 -05:00
|
|
|
rules << :destroy_project_member
|
|
|
|
end
|
2015-11-03 06:11:56 -05:00
|
|
|
end
|
2015-11-17 09:49:37 -05:00
|
|
|
|
2015-11-03 06:11:56 -05:00
|
|
|
rules
|
|
|
|
end
|
|
|
|
|
2016-02-04 05:09:42 -05:00
|
|
|
def commit_status_abilities(user, subject)
|
|
|
|
rules = project_abilities(user, subject.project)
|
|
|
|
# If subject is Ci::Build which inherits from CommitStatus filter the abilities
|
|
|
|
rules = filter_build_abilities(rules) if subject.is_a?(Ci::Build)
|
|
|
|
rules
|
|
|
|
end
|
|
|
|
|
2016-02-03 07:33:47 -05:00
|
|
|
def filter_build_abilities(rules)
|
|
|
|
# If we can't read build we should also not have that
|
|
|
|
# ability when looking at this in context of commit_status
|
2016-02-04 08:43:52 -05:00
|
|
|
%w(read create update admin).each do |rule|
|
2016-02-04 10:32:41 -05:00
|
|
|
rules.delete(:"#{rule}_commit_status") unless rules.include?(:"#{rule}_build")
|
2016-02-03 07:33:47 -05:00
|
|
|
end
|
|
|
|
rules
|
|
|
|
end
|
|
|
|
|
2016-06-29 07:04:06 -04:00
|
|
|
def runner_abilities(user, runner)
|
|
|
|
if user.is_admin?
|
|
|
|
[:assign_runner]
|
|
|
|
elsif runner.is_shared? || runner.locked?
|
|
|
|
[]
|
|
|
|
elsif user.ci_authorized_runners.include?(runner)
|
|
|
|
[:assign_runner]
|
|
|
|
else
|
|
|
|
[]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-03-30 16:14:21 -04:00
|
|
|
def user_abilities
|
2016-03-29 11:24:42 -04:00
|
|
|
[:read_user]
|
|
|
|
end
|
|
|
|
|
2014-10-19 04:50:23 -04:00
|
|
|
def abilities
|
|
|
|
@abilities ||= begin
|
2015-11-11 10:42:27 -05:00
|
|
|
abilities = Six.new
|
|
|
|
abilities << self
|
|
|
|
abilities
|
|
|
|
end
|
2014-10-19 04:50:23 -04:00
|
|
|
end
|
2015-05-22 06:17:37 -04:00
|
|
|
|
|
|
|
private
|
|
|
|
|
2016-03-30 16:14:21 -04:00
|
|
|
def restricted_public_level?
|
2016-04-06 17:09:24 -04:00
|
|
|
current_application_settings.restricted_visibility_levels.include?(Gitlab::VisibilityLevel::PUBLIC)
|
2016-03-30 16:14:21 -04:00
|
|
|
end
|
|
|
|
|
2015-05-22 06:17:37 -04:00
|
|
|
def named_abilities(name)
|
|
|
|
[
|
|
|
|
:"read_#{name}",
|
2015-06-26 11:18:40 -04:00
|
|
|
:"create_#{name}",
|
|
|
|
:"update_#{name}",
|
2015-05-22 06:17:37 -04:00
|
|
|
:"admin_#{name}"
|
|
|
|
]
|
|
|
|
end
|
2016-03-17 15:38:51 -04:00
|
|
|
|
|
|
|
def filter_confidential_issues_abilities(user, issue, rules)
|
|
|
|
return rules if user.admin? || !issue.confidential?
|
|
|
|
|
2016-06-06 15:13:31 -04:00
|
|
|
unless issue.author == user || issue.assignee == user || issue.project.team.member?(user, Gitlab::Access::REPORTER)
|
2016-03-17 15:38:51 -04:00
|
|
|
rules.delete(:admin_issue)
|
|
|
|
rules.delete(:read_issue)
|
|
|
|
rules.delete(:update_issue)
|
|
|
|
end
|
|
|
|
|
|
|
|
rules
|
|
|
|
end
|
2016-07-05 12:55:35 -04:00
|
|
|
|
|
|
|
def project_group_member?(project, user)
|
|
|
|
project.group &&
|
|
|
|
(
|
|
|
|
project.group.members.exists?(user_id: user.id) ||
|
|
|
|
project.group.requesters.exists?(user_id: user.id)
|
|
|
|
)
|
|
|
|
end
|
2011-10-17 06:39:03 -04:00
|
|
|
end
|
2011-10-08 17:36:38 -04:00
|
|
|
end
|