2013-02-06 14:46:45 -05:00
|
|
|
# The guardian is responsible for confirming access to various site resources and operations
|
2013-02-05 14:16:51 -05:00
|
|
|
class Guardian
|
|
|
|
|
|
|
|
attr_reader :user
|
2013-02-25 11:42:20 -05:00
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
def initialize(user=nil)
|
|
|
|
@user = user
|
|
|
|
end
|
|
|
|
|
|
|
|
def current_user
|
|
|
|
@user
|
|
|
|
end
|
|
|
|
|
|
|
|
def is_admin?
|
2013-04-29 02:33:24 -04:00
|
|
|
@user && @user.admin?
|
|
|
|
end
|
|
|
|
|
2013-05-02 03:22:27 -04:00
|
|
|
def is_staff?
|
|
|
|
@user && @user.staff?
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
# Can the user see the object?
|
|
|
|
def can_see?(obj)
|
|
|
|
return false if obj.blank?
|
|
|
|
|
2013-02-25 11:42:20 -05:00
|
|
|
see_method = :"can_see_#{obj.class.name.underscore}?"
|
2013-02-05 14:16:51 -05:00
|
|
|
return send(see_method, obj) if respond_to?(see_method)
|
|
|
|
|
2013-02-25 11:42:20 -05:00
|
|
|
return true
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
# Can the user edit the obj
|
|
|
|
def can_edit?(obj)
|
|
|
|
return false if obj.blank?
|
|
|
|
return false if @user.blank?
|
|
|
|
|
2013-02-25 11:42:20 -05:00
|
|
|
edit_method = :"can_edit_#{obj.class.name.underscore}?"
|
2013-02-05 14:16:51 -05:00
|
|
|
return send(edit_method, obj) if respond_to?(edit_method)
|
|
|
|
|
|
|
|
true
|
|
|
|
end
|
|
|
|
|
|
|
|
# Can we delete the object
|
|
|
|
def can_delete?(obj)
|
|
|
|
return false if obj.blank?
|
2013-02-25 11:42:20 -05:00
|
|
|
return false if @user.blank?
|
2013-02-05 14:16:51 -05:00
|
|
|
|
|
|
|
delete_method = :"can_delete_#{obj.class.name.underscore}?"
|
|
|
|
return send(delete_method, obj) if respond_to?(delete_method)
|
|
|
|
|
|
|
|
true
|
|
|
|
end
|
|
|
|
|
|
|
|
def can_moderate?(obj)
|
|
|
|
return false if obj.blank?
|
|
|
|
return false if @user.blank?
|
2013-05-02 03:22:27 -04:00
|
|
|
@user.staff?
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
2013-02-25 11:42:20 -05:00
|
|
|
alias :can_move_posts? :can_moderate?
|
2013-02-05 14:16:51 -05:00
|
|
|
alias :can_see_flags? :can_moderate?
|
2013-05-07 21:58:34 -04:00
|
|
|
alias :can_send_activation_email? :can_moderate?
|
2013-02-05 14:16:51 -05:00
|
|
|
|
|
|
|
# Can the user create a topic in the forum
|
|
|
|
def can_create?(klass, parent=nil)
|
|
|
|
return false if klass.blank?
|
|
|
|
return false if @user.blank?
|
|
|
|
|
|
|
|
# If no parent is provided, we look for a can_i_create_klass?
|
|
|
|
# custom method.
|
|
|
|
#
|
|
|
|
# If a parent is provided, we look for a method called
|
|
|
|
# can_i_create_klass_on_parent?
|
|
|
|
target = klass.name.underscore
|
|
|
|
if parent.present?
|
|
|
|
return false unless can_see?(parent)
|
|
|
|
target << "_on_#{parent.class.name.underscore}"
|
|
|
|
end
|
2013-02-25 11:42:20 -05:00
|
|
|
create_method = :"can_create_#{target}?"
|
2013-02-05 14:16:51 -05:00
|
|
|
|
|
|
|
return send(create_method, parent) if respond_to?(create_method)
|
|
|
|
|
|
|
|
true
|
2013-02-25 11:42:20 -05:00
|
|
|
end
|
2013-02-05 14:16:51 -05:00
|
|
|
|
|
|
|
# Can we impersonate this user?
|
|
|
|
def can_impersonate?(target)
|
|
|
|
return false if target.blank?
|
|
|
|
return false if @user.blank?
|
|
|
|
|
|
|
|
# You must be an admin to impersonate
|
|
|
|
return false unless @user.admin?
|
|
|
|
|
|
|
|
# You may not impersonate other admins
|
|
|
|
return false if target.admin?
|
|
|
|
|
|
|
|
# You may not impersonate yourself
|
|
|
|
return false if @user == target
|
|
|
|
|
|
|
|
true
|
|
|
|
end
|
|
|
|
|
|
|
|
# Can we approve it?
|
|
|
|
def can_approve?(target)
|
|
|
|
return false if target.blank?
|
|
|
|
return false if @user.blank?
|
|
|
|
return false if target.approved?
|
2013-05-02 03:22:27 -04:00
|
|
|
@user.staff?
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
2013-05-07 21:58:34 -04:00
|
|
|
alias :can_activate? :can_approve?
|
2013-02-05 14:16:51 -05:00
|
|
|
|
|
|
|
def can_ban?(user)
|
2013-05-21 02:39:51 -04:00
|
|
|
is_staff? && user && !user.staff?
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
2013-05-21 02:39:51 -04:00
|
|
|
|
2013-05-07 21:58:34 -04:00
|
|
|
alias :can_deactivate? :can_ban?
|
2013-02-05 14:16:51 -05:00
|
|
|
|
2013-02-08 19:04:14 -05:00
|
|
|
def can_clear_flags?(post)
|
|
|
|
return false if @user.blank?
|
|
|
|
return false if post.blank?
|
2013-05-02 03:22:27 -04:00
|
|
|
@user.staff?
|
2013-02-08 19:04:14 -05:00
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
def can_revoke_admin?(admin)
|
|
|
|
return false unless @user.try(:admin?)
|
|
|
|
return false if admin.blank?
|
|
|
|
return false if @user.id == admin.id
|
|
|
|
return false unless admin.admin?
|
|
|
|
true
|
|
|
|
end
|
|
|
|
|
|
|
|
def can_grant_admin?(user)
|
|
|
|
return false unless @user.try(:admin?)
|
|
|
|
return false if user.blank?
|
|
|
|
return false if @user.id == user.id
|
|
|
|
return false if user.admin?
|
|
|
|
true
|
|
|
|
end
|
|
|
|
|
2013-02-12 17:58:08 -05:00
|
|
|
def can_revoke_moderation?(moderator)
|
2013-05-02 03:22:27 -04:00
|
|
|
return false unless is_admin?
|
2013-02-12 17:58:08 -05:00
|
|
|
return false if moderator.blank?
|
2013-05-09 03:37:34 -04:00
|
|
|
return false if @user.id == moderator.id && !is_admin?
|
|
|
|
return false unless moderator.moderator?
|
2013-02-12 17:58:08 -05:00
|
|
|
true
|
|
|
|
end
|
|
|
|
|
|
|
|
def can_grant_moderation?(user)
|
2013-05-09 03:37:34 -04:00
|
|
|
return false unless is_admin?
|
|
|
|
return false unless user
|
|
|
|
return false if @user.id == user.id && !is_admin?
|
|
|
|
return false if user.moderator?
|
2013-02-12 17:58:08 -05:00
|
|
|
true
|
|
|
|
end
|
|
|
|
|
2013-04-11 16:04:20 -04:00
|
|
|
def can_delete_user?(user_to_delete)
|
2013-05-02 03:22:27 -04:00
|
|
|
return false unless is_admin?
|
|
|
|
return false unless user_to_delete
|
2013-04-11 16:04:20 -04:00
|
|
|
return false if user_to_delete.post_count > 0
|
|
|
|
true
|
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
# Can we see who acted on a post in a particular way?
|
|
|
|
def can_see_post_actors?(topic, post_action_type_id)
|
2013-05-02 03:22:27 -04:00
|
|
|
return false unless topic
|
2013-02-05 14:16:51 -05:00
|
|
|
|
2013-03-01 07:07:44 -05:00
|
|
|
type_symbol = PostActionType.types[post_action_type_id]
|
2013-02-05 14:16:51 -05:00
|
|
|
return false if type_symbol == :bookmark
|
|
|
|
return can_see_flags?(topic) if PostActionType.is_flag?(type_symbol)
|
|
|
|
|
|
|
|
if type_symbol == :vote
|
|
|
|
# We can see votes if the topic allows for public voting
|
|
|
|
return false if topic.has_meta_data_boolean?(:private_poll)
|
|
|
|
end
|
|
|
|
|
|
|
|
true
|
|
|
|
end
|
|
|
|
|
2013-04-03 12:23:28 -04:00
|
|
|
# Support sites that have to approve users
|
|
|
|
def can_access_forum?
|
|
|
|
return true unless SiteSetting.must_approve_users?
|
2013-05-02 03:22:27 -04:00
|
|
|
return false unless @user
|
2013-04-03 12:23:28 -04:00
|
|
|
|
2013-05-02 03:22:27 -04:00
|
|
|
# Staff can't lock themselves out of a site
|
|
|
|
return true if is_staff?
|
2013-04-03 12:23:28 -04:00
|
|
|
|
2013-05-02 03:22:27 -04:00
|
|
|
@user.approved?
|
2013-04-03 12:23:28 -04:00
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
def can_see_pending_invites_from?(user)
|
2013-05-02 03:22:27 -04:00
|
|
|
return false unless user && @user
|
2013-02-05 14:16:51 -05:00
|
|
|
return user == @user
|
|
|
|
end
|
|
|
|
|
|
|
|
# For now, can_invite_to is basically can_see?
|
|
|
|
def can_invite_to?(object)
|
2013-05-02 03:22:27 -04:00
|
|
|
return false unless @user
|
2013-02-05 14:16:51 -05:00
|
|
|
return false unless can_see?(object)
|
|
|
|
return false if SiteSetting.must_approve_users?
|
2013-05-02 03:22:27 -04:00
|
|
|
@user.has_trust_level?(:regular) || @user.staff?
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
def can_see_deleted_posts?
|
2013-05-02 03:22:27 -04:00
|
|
|
return true if is_staff?
|
2013-02-05 14:16:51 -05:00
|
|
|
false
|
|
|
|
end
|
|
|
|
|
|
|
|
def can_see_private_messages?(user_id)
|
2013-05-02 03:22:27 -04:00
|
|
|
return true if is_staff?
|
|
|
|
return false unless @user
|
2013-02-05 14:16:51 -05:00
|
|
|
@user.id == user_id
|
|
|
|
end
|
|
|
|
|
2013-02-07 02:11:56 -05:00
|
|
|
def can_delete_all_posts?(user)
|
2013-05-03 03:56:23 -04:00
|
|
|
return false unless is_staff?
|
2013-02-07 02:11:56 -05:00
|
|
|
return false if user.created_at < 7.days.ago
|
|
|
|
|
2013-02-25 11:42:20 -05:00
|
|
|
true
|
2013-02-07 02:11:56 -05:00
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
# Support for ensure_{blah}! methods.
|
|
|
|
def method_missing(method, *args, &block)
|
|
|
|
if method.to_s =~ /^ensure_(.*)\!$/
|
|
|
|
can_method = :"#{Regexp.last_match[1]}?"
|
|
|
|
|
|
|
|
if respond_to?(can_method)
|
2013-02-25 11:42:20 -05:00
|
|
|
raise Discourse::InvalidAccess.new("#{can_method} failed") unless send(can_method, *args, &block)
|
2013-02-05 14:16:51 -05:00
|
|
|
return
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
super.method_missing(method, *args, &block)
|
|
|
|
end
|
|
|
|
|
|
|
|
# Make sure we can see the object. Will raise a NotFound if it's nil
|
|
|
|
def ensure_can_see!(obj)
|
|
|
|
raise Discourse::InvalidAccess.new("Can't see #{obj}") unless can_see?(obj)
|
|
|
|
end
|
|
|
|
|
|
|
|
# Creating Methods
|
|
|
|
def can_create_category?(parent)
|
2013-05-02 03:22:27 -04:00
|
|
|
is_staff?
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def can_create_post_on_topic?(topic)
|
2013-05-02 03:22:27 -04:00
|
|
|
return true if is_staff?
|
2013-02-05 14:16:51 -05:00
|
|
|
return false if topic.closed?
|
|
|
|
return false if topic.archived?
|
|
|
|
true
|
|
|
|
end
|
|
|
|
|
|
|
|
# Editing Methods
|
|
|
|
def can_edit_category?(category)
|
2013-05-02 03:22:27 -04:00
|
|
|
is_staff?
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def can_edit_post?(post)
|
2013-05-02 03:22:27 -04:00
|
|
|
return true if is_staff?
|
2013-02-05 14:16:51 -05:00
|
|
|
return false if post.topic.archived?
|
|
|
|
(post.user == @user)
|
|
|
|
end
|
|
|
|
|
|
|
|
def can_edit_user?(user)
|
|
|
|
return true if user == @user
|
2013-05-02 03:22:27 -04:00
|
|
|
is_staff?
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def can_edit_topic?(topic)
|
2013-05-02 03:22:27 -04:00
|
|
|
return true if is_staff?
|
2013-02-05 14:16:51 -05:00
|
|
|
return true if topic.user == @user
|
|
|
|
false
|
|
|
|
end
|
|
|
|
|
|
|
|
# Deleting Methods
|
|
|
|
def can_delete_post?(post)
|
|
|
|
# Can't delete the first post
|
|
|
|
return false if post.post_number == 1
|
2013-02-25 11:42:20 -05:00
|
|
|
|
2013-02-07 15:12:55 -05:00
|
|
|
# You can delete your own posts
|
|
|
|
return !post.user_deleted? if post.user == @user
|
|
|
|
|
2013-05-02 03:22:27 -04:00
|
|
|
is_staff?
|
2013-02-07 15:12:55 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
# Recovery Method
|
|
|
|
def can_recover_post?(post)
|
2013-05-02 03:22:27 -04:00
|
|
|
return false unless @user
|
|
|
|
is_staff?
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def can_delete_category?(category)
|
2013-05-02 03:22:27 -04:00
|
|
|
return false unless is_staff?
|
2013-02-25 11:42:20 -05:00
|
|
|
return category.topic_count == 0
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def can_delete_topic?(topic)
|
2013-05-02 03:22:27 -04:00
|
|
|
return false unless is_staff?
|
2013-02-25 11:42:20 -05:00
|
|
|
return false if Category.exists?(topic_id: topic.id)
|
2013-02-05 14:16:51 -05:00
|
|
|
true
|
|
|
|
end
|
|
|
|
|
|
|
|
def can_delete_post_action?(post_action)
|
2013-02-25 11:42:20 -05:00
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
# You can only undo your own actions
|
2013-03-19 19:51:24 -04:00
|
|
|
return false unless @user
|
|
|
|
return false unless post_action.user_id == @user.id
|
2013-04-12 03:55:45 -04:00
|
|
|
return false if post_action.is_private_message?
|
2013-02-05 14:16:51 -05:00
|
|
|
|
|
|
|
# Make sure they want to delete it within the window
|
|
|
|
return post_action.created_at > SiteSetting.post_undo_action_window_mins.minutes.ago
|
|
|
|
end
|
|
|
|
|
2013-05-02 01:15:17 -04:00
|
|
|
def can_send_private_message?(target)
|
|
|
|
return false unless User === target || Group === target
|
2013-05-02 03:22:27 -04:00
|
|
|
return false unless @user
|
2013-02-05 14:16:51 -05:00
|
|
|
|
2013-02-25 11:42:20 -05:00
|
|
|
# Can't send message to yourself
|
2013-05-02 01:15:17 -04:00
|
|
|
return false if User === target && @user.id == target.id
|
2013-02-05 14:16:51 -05:00
|
|
|
|
|
|
|
# Have to be a basic level at least
|
|
|
|
return false unless @user.has_trust_level?(:basic)
|
2013-02-25 11:42:20 -05:00
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
SiteSetting.enable_private_messages
|
|
|
|
end
|
|
|
|
|
|
|
|
def can_reply_as_new_topic?(topic)
|
2013-05-02 03:22:27 -04:00
|
|
|
return false unless @user
|
|
|
|
return false unless topic
|
2013-02-05 14:16:51 -05:00
|
|
|
return false if topic.private_message?
|
|
|
|
|
|
|
|
@user.has_trust_level?(:basic)
|
|
|
|
end
|
|
|
|
|
|
|
|
def can_see_topic?(topic)
|
2013-04-29 02:33:24 -04:00
|
|
|
return false unless topic
|
|
|
|
|
2013-05-02 03:22:27 -04:00
|
|
|
return true if @user && is_staff?
|
2013-05-02 01:15:17 -04:00
|
|
|
return false if topic.deleted_at
|
2013-04-29 02:33:24 -04:00
|
|
|
|
|
|
|
if topic.category && topic.category.secure
|
|
|
|
return false unless @user && can_see_category?(topic.category)
|
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
if topic.private_message?
|
2013-05-02 01:15:17 -04:00
|
|
|
return false unless @user
|
|
|
|
return true if topic.all_allowed_users.where(id: @user.id).exists?
|
2013-02-05 14:16:51 -05:00
|
|
|
return is_admin?
|
|
|
|
end
|
|
|
|
true
|
|
|
|
end
|
|
|
|
|
2013-04-29 02:33:24 -04:00
|
|
|
def can_see_post?(post)
|
|
|
|
return false unless post
|
|
|
|
|
2013-05-02 03:22:27 -04:00
|
|
|
return true if @user && is_staff?
|
2013-04-29 02:33:24 -04:00
|
|
|
return false if post.deleted_at.present?
|
|
|
|
|
|
|
|
can_see_topic?(post.topic)
|
|
|
|
end
|
|
|
|
|
|
|
|
def can_see_category?(category)
|
|
|
|
return true unless category.secure
|
|
|
|
return false unless @user
|
|
|
|
|
2013-05-13 04:04:03 -04:00
|
|
|
secure_category_ids.include?(category.id)
|
2013-04-29 02:33:24 -04:00
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
def can_vote?(post, opts={})
|
|
|
|
post_can_act?(post,:vote, opts)
|
|
|
|
end
|
|
|
|
|
2013-02-25 11:42:20 -05:00
|
|
|
# Can the user act on the post in a particular way.
|
2013-02-05 14:16:51 -05:00
|
|
|
# taken_actions = the list of actions the user has already taken
|
|
|
|
def post_can_act?(post, action_key, opts={})
|
2013-02-25 11:42:20 -05:00
|
|
|
return false if @user.blank?
|
2013-02-05 14:16:51 -05:00
|
|
|
return false if post.blank?
|
|
|
|
|
|
|
|
taken = opts[:taken_actions]
|
|
|
|
taken = taken.keys if taken
|
|
|
|
|
2013-05-02 01:15:17 -04:00
|
|
|
# we always allow flagging
|
2013-02-05 14:16:51 -05:00
|
|
|
if PostActionType.is_flag?(action_key)
|
|
|
|
return false unless @user.has_trust_level?(:basic)
|
|
|
|
|
|
|
|
if taken
|
2013-03-01 07:07:44 -05:00
|
|
|
return false unless (taken & PostActionType.flag_types.values).empty?
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
2013-02-25 11:42:20 -05:00
|
|
|
else
|
2013-03-01 07:07:44 -05:00
|
|
|
return false if taken && taken.include?(PostActionType.types[action_key])
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
2013-05-02 01:15:17 -04:00
|
|
|
# nothing else on archived posts
|
|
|
|
return false if post.topic.archived?
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
case action_key
|
|
|
|
when :like
|
2013-02-25 11:42:20 -05:00
|
|
|
return false if post.user == @user
|
|
|
|
when :vote then
|
2013-03-04 19:42:44 -05:00
|
|
|
return false if opts[:voted_in_topic] && post.topic.has_meta_data_boolean?(:single_vote)
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
2013-04-29 02:33:24 -04:00
|
|
|
def secure_category_ids
|
2013-05-13 04:04:03 -04:00
|
|
|
@secure_category_ids ||= @user ? @user.secure_category_ids : []
|
2013-04-29 02:33:24 -04:00
|
|
|
end
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|