2011-10-08 21:36:38 +00:00
|
|
|
class Ability
|
2012-10-09 00:10:04 +00:00
|
|
|
class << self
|
2016-08-24 00:29:40 +00: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
|
2016-08-08 17:07:15 +00:00
|
|
|
|
2016-08-24 00:29:40 +00:00
|
|
|
# Returns an Array of Issues that can be read by the given user.
|
|
|
|
#
|
|
|
|
# issues - The issues to reduce down to those readable by the user.
|
|
|
|
# user - The User for which to check the issues
|
|
|
|
def issues_readable_by_user(issues, user = nil)
|
|
|
|
return issues if user && user.admin?
|
|
|
|
|
|
|
|
issues.select { |issue| issue.visible_to_user?(user) }
|
|
|
|
end
|
|
|
|
|
|
|
|
# TODO: make this private and use the actual abilities stuff for this
|
|
|
|
def can_edit_note?(user, note)
|
|
|
|
return false if !note.editable? || !user.present?
|
|
|
|
return true if note.author == user || user.admin?
|
|
|
|
|
|
|
|
if note.project
|
|
|
|
max_access_level = note.project.team.max_member_access(user.id)
|
|
|
|
max_access_level >= Gitlab::Access::MASTER
|
|
|
|
else
|
|
|
|
false
|
|
|
|
end
|
2016-08-08 17:07:15 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def allowed?(user, action, subject)
|
|
|
|
allowed(user, subject).include?(action)
|
|
|
|
end
|
|
|
|
|
2013-01-25 09:30:49 +00:00
|
|
|
def allowed(user, subject)
|
2016-08-08 17:07:15 +00:00
|
|
|
return uncached_allowed(user, subject) unless RequestStore.active?
|
|
|
|
|
|
|
|
user_key = user ? user.id : 'anonymous'
|
|
|
|
subject_key = subject ? "#{subject.class.name}/#{subject.id}" : 'global'
|
|
|
|
key = "/ability/#{user_key}/#{subject_key}"
|
|
|
|
RequestStore[key] ||= Set.new(uncached_allowed(user, subject)).freeze
|
|
|
|
end
|
|
|
|
|
2016-08-24 00:29:40 +00:00
|
|
|
private
|
|
|
|
|
2016-08-08 17:07:15 +00:00
|
|
|
def uncached_allowed(user, subject)
|
2016-08-16 19:55:44 +00:00
|
|
|
policy_class = BasePolicy.class_for(subject) rescue nil
|
|
|
|
return policy_class.abilities(user, subject) if policy_class
|
|
|
|
|
2016-08-08 17:07:15 +00:00
|
|
|
return anonymous_abilities(subject) if user.nil?
|
2015-11-17 15:24:02 +00:00
|
|
|
return [] unless user.is_a?(User)
|
2013-08-27 09:41:49 +00:00
|
|
|
return [] if user.blocked?
|
2013-01-25 09:30:49 +00:00
|
|
|
|
2016-08-04 14:00:31 +00:00
|
|
|
abilities_by_subject_class(user: user, subject: subject)
|
|
|
|
end
|
|
|
|
|
|
|
|
def abilities_by_subject_class(user:, subject:)
|
2016-02-04 13:43:52 +00:00
|
|
|
case subject
|
2016-06-15 10:12:26 +00:00
|
|
|
when ExternalIssue, Deployment, Environment then project_abilities(user, subject.project)
|
2015-11-12 08:43:30 +00:00
|
|
|
else []
|
2016-08-11 22:12:52 +00:00
|
|
|
end + global_abilities(user)
|
2013-01-25 09:30:49 +00:00
|
|
|
end
|
|
|
|
|
2015-11-17 20:00:14 +00:00
|
|
|
# List of possible abilities for anonymous user
|
2016-08-16 18:10:34 +00:00
|
|
|
def anonymous_abilities(subject)
|
2016-08-16 22:31:01 +00:00
|
|
|
if subject.respond_to?(:project)
|
2016-08-12 18:36:16 +00:00
|
|
|
ProjectPolicy.abilities(nil, subject.project)
|
2016-08-16 23:28:47 +00:00
|
|
|
elsif subject.respond_to?(:group)
|
|
|
|
GroupPolicy.abilities(nil, subject.group)
|
2015-11-17 15:24:02 +00:00
|
|
|
else
|
|
|
|
[]
|
|
|
|
end
|
2015-10-29 20:42:29 +00:00
|
|
|
end
|
|
|
|
|
2013-01-25 09:30:49 +00:00
|
|
|
def global_abilities(user)
|
|
|
|
rules = []
|
|
|
|
rules << :create_group if user.can_create_group
|
2016-04-12 15:04:33 +00:00
|
|
|
rules << :read_users_list
|
2013-01-25 09:30:49 +00:00
|
|
|
rules
|
2011-10-08 21:36:38 +00:00
|
|
|
end
|
|
|
|
|
2012-10-09 00:10:04 +00:00
|
|
|
def project_abilities(user, project)
|
2016-08-11 22:12:52 +00:00
|
|
|
# temporary patch, deleteme before merge
|
2016-08-12 18:36:16 +00:00
|
|
|
ProjectPolicy.abilities(user, project).to_a
|
2015-07-19 21:21:33 +00:00
|
|
|
end
|
|
|
|
|
2015-11-03 11:11:56 +00:00
|
|
|
def project_member_abilities(user, subject)
|
|
|
|
rules = []
|
|
|
|
target_user = subject.user
|
|
|
|
project = subject.project
|
|
|
|
|
2016-07-05 16:55:35 +00:00
|
|
|
unless target_user == project.owner
|
2016-08-16 23:29:10 +00:00
|
|
|
can_manage = allowed?(user, :admin_project_member, project)
|
2015-11-03 11:11:56 +00:00
|
|
|
|
2015-12-01 22:47:26 +00:00
|
|
|
if can_manage
|
2015-11-17 14:49:37 +00:00
|
|
|
rules << :update_project_member
|
|
|
|
rules << :destroy_project_member
|
2015-12-01 22:47:26 +00:00
|
|
|
elsif user == target_user
|
2015-11-17 14:49:37 +00:00
|
|
|
rules << :destroy_project_member
|
|
|
|
end
|
2015-11-03 11:11:56 +00:00
|
|
|
end
|
2015-11-17 14:49:37 +00:00
|
|
|
|
2015-11-03 11:11:56 +00:00
|
|
|
rules
|
|
|
|
end
|
|
|
|
|
2016-02-03 12:33:47 +00: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 13:43:52 +00:00
|
|
|
%w(read create update admin).each do |rule|
|
2016-02-04 15:32:41 +00:00
|
|
|
rules.delete(:"#{rule}_commit_status") unless rules.include?(:"#{rule}_build")
|
2016-02-03 12:33:47 +00:00
|
|
|
end
|
|
|
|
rules
|
|
|
|
end
|
|
|
|
|
2016-03-30 20:14:21 +00:00
|
|
|
def restricted_public_level?
|
2016-04-06 21:09:24 +00:00
|
|
|
current_application_settings.restricted_visibility_levels.include?(Gitlab::VisibilityLevel::PUBLIC)
|
2016-03-30 20:14:21 +00:00
|
|
|
end
|
|
|
|
|
2016-03-17 19:38:51 +00:00
|
|
|
def filter_confidential_issues_abilities(user, issue, rules)
|
|
|
|
return rules if user.admin? || !issue.confidential?
|
|
|
|
|
2016-06-06 19:13:31 +00:00
|
|
|
unless issue.author == user || issue.assignee == user || issue.project.team.member?(user, Gitlab::Access::REPORTER)
|
2016-03-17 19:38:51 +00:00
|
|
|
rules.delete(:admin_issue)
|
|
|
|
rules.delete(:read_issue)
|
|
|
|
rules.delete(:update_issue)
|
|
|
|
end
|
|
|
|
|
|
|
|
rules
|
|
|
|
end
|
2011-10-17 10:39:03 +00:00
|
|
|
end
|
2011-10-08 21:36:38 +00:00
|
|
|
end
|