summaryrefslogtreecommitdiff
path: root/app/models/ability.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/ability.rb')
-rw-r--r--app/models/ability.rb73
1 files changed, 26 insertions, 47 deletions
diff --git a/app/models/ability.rb b/app/models/ability.rb
index ad6c588202e..0b6bcbde5d9 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -1,35 +1,20 @@
+require_dependency 'declarative_policy'
+
class Ability
class << self
# 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
+ DeclarativePolicy.subject_scope do
+ users.select { |u| allowed?(u, :read_project, project) }
end
end
# Given a list of users and a snippet this method returns the users that can
# read the given snippet.
def users_that_can_read_personal_snippet(users, snippet)
- case snippet.visibility_level
- when Snippet::INTERNAL, Snippet::PUBLIC
- users
- when Snippet::PRIVATE
- users.include?(snippet.author) ? [snippet.author] : []
+ DeclarativePolicy.subject_scope do
+ users.select { |u| allowed?(u, :read_personal_snippet, snippet) }
end
end
@@ -38,41 +23,35 @@ class Ability
# 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) }
+ DeclarativePolicy.user_scope do
+ issues.select { |issue| issue.visible_to_user?(user) }
+ end
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
+ allowed?(user, :edit_note, note)
end
- def allowed?(user, action, subject)
- allowed(user, subject).include?(action)
- end
+ def allowed?(user, action, subject = :global, opts = {})
+ if subject.is_a?(Hash)
+ opts, subject = subject, :global
+ end
- def allowed(user, subject)
- return uncached_allowed(user, subject) unless RequestStore.active?
+ policy = policy_for(user, subject)
- user_key = user ? user.id : 'anonymous'
- subject_key = subject ? "#{subject.class.name}/#{subject.id}" : 'global'
- 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