2013-02-06 17:46:45 -02:00
# The guardian is responsible for confirming access to various site resources and operations
2013-02-05 14:16:51 -05:00
class Guardian
2013-05-19 23:04:53 -07:00
class AnonymousUser
def blank? ; true ; end
def admin? ; false ; end
def staff? ; false ; end
def approved? ; false ; end
def secure_category_ids ; [ ] ; end
def has_trust_level? ( level ) ; false ; end
end
2013-02-25 19:42:20 +03:00
2013-02-05 14:16:51 -05:00
def initialize ( user = nil )
2013-05-19 23:04:53 -07:00
@user = user . presence || AnonymousUser . new
end
def user
@user . presence
end
alias :current_user :user
def anonymous?
! authenticated?
2013-02-05 14:16:51 -05:00
end
2013-05-19 23:04:53 -07:00
def authenticated?
@user . present?
2013-02-05 14:16:51 -05:00
end
def is_admin?
2013-05-19 23:04:53 -07:00
@user . admin?
2013-04-29 16:33:24 +10:00
end
2013-05-02 17:22:27 +10:00
def is_staff?
2013-05-19 23:04:53 -07:00
@user . staff?
2013-02-05 14:16:51 -05:00
end
# Can the user see the object?
def can_see? ( obj )
2013-05-19 23:04:53 -07:00
if obj
see_method = method_name_for :see , obj
return ( see_method ? send ( see_method , obj ) : true )
end
2013-02-05 14:16:51 -05:00
end
# Can the user edit the obj
def can_edit? ( obj )
2013-05-19 23:04:53 -07:00
if obj && authenticated?
edit_method = method_name_for :edit , obj
return ( edit_method ? send ( edit_method , obj ) : true )
end
2013-02-05 14:16:51 -05:00
end
# Can we delete the object
def can_delete? ( obj )
2013-05-19 23:04:53 -07:00
if obj && authenticated?
delete_method = method_name_for :delete , obj
return ( delete_method ? send ( delete_method , obj ) : true )
end
2013-02-05 14:16:51 -05:00
end
def can_moderate? ( obj )
2013-05-19 23:04:53 -07:00
obj && is_staff?
2013-02-05 14:16:51 -05:00
end
2013-02-25 19:42:20 +03: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 )
2013-05-19 23:04:53 -07:00
return false unless authenticated? && klass
2013-02-05 14:16:51 -05:00
# 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 19:42:20 +03: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 19:42:20 +03:00
end
2013-02-05 14:16:51 -05:00
# Can we impersonate this user?
def can_impersonate? ( target )
2013-05-19 23:04:53 -07:00
target &&
2013-02-05 14:16:51 -05:00
# You must be an admin to impersonate
2013-05-19 23:04:53 -07:00
is_admin? &&
2013-02-05 14:16:51 -05:00
# You may not impersonate other admins
2013-05-19 23:04:53 -07:00
not ( target . admin? )
2013-02-05 14:16:51 -05:00
2013-05-19 23:04:53 -07:00
# Additionally, you may not impersonate yourself;
# but the two tests for different admin statuses
# make it impossible to be the same user.
2013-02-05 14:16:51 -05:00
end
# Can we approve it?
def can_approve? ( target )
2013-05-19 23:04:53 -07:00
is_staff? && target && not ( target . approved? )
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-19 23:04:53 -07:00
user && is_staff? && not ( user . staff? )
2013-02-05 14:16:51 -05:00
end
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 )
2013-05-19 23:04:53 -07:00
is_staff? && post
2013-02-08 19:04:14 -05:00
end
2013-02-05 14:16:51 -05:00
def can_revoke_admin? ( admin )
2013-05-19 23:04:53 -07:00
can_administer_user? ( admin ) && admin . admin?
2013-02-05 14:16:51 -05:00
end
def can_grant_admin? ( user )
2013-05-19 23:04:53 -07:00
can_administer_user? ( user ) && not ( user . admin? )
2013-02-05 14:16:51 -05:00
end
2013-02-12 22:58:08 +00:00
def can_revoke_moderation? ( moderator )
2013-05-19 23:04:53 -07:00
can_administer? ( moderator ) && moderator . moderator?
2013-02-12 22:58:08 +00:00
end
def can_grant_moderation? ( user )
2013-05-19 23:04:53 -07:00
can_administer? ( user ) && not ( user . moderator? )
2013-02-12 22:58:08 +00:00
end
2013-04-11 16:04:20 -04:00
def can_delete_user? ( user_to_delete )
2013-05-19 23:04:53 -07:00
can_administer? ( user_to_delete ) && user_to_delete . post_count < = 0
2013-04-11 16:04:20 -04:00
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 17:22:27 +10:00
return false unless topic
2013-02-05 14:16:51 -05:00
2013-03-01 15:07:44 +03: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 17:22:27 +10:00
return false unless @user
2013-04-03 12:23:28 -04:00
2013-05-02 17:22:27 +10: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 17:22:27 +10: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-19 23:04:53 -07:00
is_me? ( user )
2013-02-05 14:16:51 -05:00
end
# For now, can_invite_to is basically can_see?
def can_invite_to? ( object )
2013-05-19 23:04:53 -07:00
authenticated? && can_see? ( object ) &&
not ( SiteSetting . must_approve_users? ) &&
( @user . has_trust_level? ( :regular ) || is_staff? )
2013-02-05 14:16:51 -05:00
end
def can_see_deleted_posts?
2013-05-19 23:04:53 -07:00
is_staff?
2013-02-05 14:16:51 -05:00
end
def can_see_private_messages? ( user_id )
2013-05-19 23:04:53 -07:00
is_staff? || ( authenticated? && @user . id == user_id )
2013-02-05 14:16:51 -05:00
end
2013-02-07 18:11:56 +11:00
def can_delete_all_posts? ( user )
2013-05-19 23:04:53 -07:00
is_staff? && user . created_at > = 7 . days . ago
2013-02-07 18:11:56 +11: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 19:42:20 +03: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 17:22:27 +10:00
is_staff?
2013-02-05 14:16:51 -05:00
end
def can_create_post_on_topic? ( topic )
2013-05-19 23:04:53 -07:00
is_staff? || not ( topic . closed? || topic . archived? )
2013-02-05 14:16:51 -05:00
end
# Editing Methods
def can_edit_category? ( category )
2013-05-02 17:22:27 +10:00
is_staff?
2013-02-05 14:16:51 -05:00
end
def can_edit_post? ( post )
2013-05-19 23:04:53 -07:00
is_staff? || ( not ( post . topic . archived? ) && is_my_own? ( post ) )
2013-02-05 14:16:51 -05:00
end
def can_edit_user? ( user )
2013-05-19 23:04:53 -07:00
is_me? ( user ) || is_staff?
2013-02-05 14:16:51 -05:00
end
def can_edit_topic? ( topic )
2013-05-19 23:04:53 -07:00
is_staff? || is_my_own? ( topic )
2013-02-05 14:16:51 -05:00
end
# Deleting Methods
def can_delete_post? ( post )
# Can't delete the first post
return false if post . post_number == 1
2013-02-25 19:42:20 +03:00
2013-02-07 15:12:55 -05:00
# You can delete your own posts
2013-05-19 23:04:53 -07:00
return ! post . user_deleted? if is_my_own? ( post )
2013-02-07 15:12:55 -05:00
2013-05-02 17:22:27 +10:00
is_staff?
2013-02-07 15:12:55 -05:00
end
# Recovery Method
def can_recover_post? ( post )
2013-05-02 17:22:27 +10:00
is_staff?
2013-02-05 14:16:51 -05:00
end
def can_delete_category? ( category )
2013-05-19 23:04:53 -07:00
is_staff? && category . topic_count == 0
2013-02-05 14:16:51 -05:00
end
def can_delete_topic? ( topic )
2013-05-19 23:04:53 -07:00
is_staff? && not ( Category . exists? ( topic_id : topic . id ) )
2013-02-05 14:16:51 -05:00
end
def can_delete_post_action? ( post_action )
# You can only undo your own actions
2013-05-19 23:04:53 -07:00
is_my_own? ( post_action ) && not ( post_action . is_private_message? ) &&
2013-02-05 14:16:51 -05:00
# Make sure they want to delete it within the window
2013-05-19 23:04:53 -07:00
post_action . created_at > SiteSetting . post_undo_action_window_mins . minutes . ago
2013-02-05 14:16:51 -05:00
end
2013-05-02 15:15:17 +10:00
def can_send_private_message? ( target )
2013-05-19 23:04:53 -07:00
( User === target || Group === target ) &&
authenticated? &&
2013-02-05 14:16:51 -05:00
2013-02-25 19:42:20 +03:00
# Can't send message to yourself
2013-05-19 23:04:53 -07:00
is_not_me? ( target ) &&
2013-02-05 14:16:51 -05:00
# Have to be a basic level at least
2013-05-19 23:04:53 -07:00
@user . has_trust_level? ( :basic ) &&
2013-02-25 19:42:20 +03:00
2013-02-05 14:16:51 -05:00
SiteSetting . enable_private_messages
end
def can_reply_as_new_topic? ( topic )
2013-05-19 23:04:53 -07:00
authenticated? && topic && not ( topic . private_message? ) && @user . has_trust_level? ( :basic )
2013-02-05 14:16:51 -05:00
end
def can_see_topic? ( topic )
2013-05-19 23:04:53 -07:00
if topic
is_staff? ||
2013-04-29 16:33:24 +10:00
2013-05-19 23:04:53 -07:00
topic . deleted_at . nil? &&
2013-04-29 16:33:24 +10:00
2013-05-19 23:04:53 -07:00
# not secure, or I can see it
( not ( topic . secure_category? ) || can_see_category? ( topic . category ) ) &&
2013-04-29 16:33:24 +10:00
2013-05-19 23:04:53 -07:00
# not private, or I am allowed (or an admin)
( not ( topic . private_message? ) || authenticated? && ( topic . all_allowed_users . where ( id : @user . id ) . exists? || is_admin? ) )
2013-02-05 14:16:51 -05:00
end
end
2013-04-29 16:33:24 +10:00
def can_see_post? ( post )
2013-05-19 23:04:53 -07:00
post . present? && ( is_staff? || ( ! post . deleted_at . present? && can_see_topic? ( post . topic ) ) )
2013-04-29 16:33:24 +10:00
end
def can_see_category? ( category )
2013-05-19 23:04:53 -07:00
not ( category . secure ) || secure_category_ids . include? ( category . id )
2013-04-29 16:33:24 +10: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 19:42:20 +03: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-05-19 23:04:53 -07:00
taken = opts [ :taken_actions ] . try ( :keys ) . to_a
is_flag = PostActionType . is_flag? ( action_key )
already_taken_this_action = taken . any? && taken . include? ( PostActionType . types [ action_key ] )
already_did_flagging = taken . any? && ( taken & PostActionType . flag_types . values ) . any?
2013-02-05 14:16:51 -05:00
2013-05-19 23:04:53 -07:00
if authenticated? && post
# we always allow flagging - NOTE: this does not seem true, see specs. (MVH)
( is_flag && @user . has_trust_level? ( :basic ) && not ( already_did_flagging ) ) ||
2013-02-05 14:16:51 -05:00
2013-05-19 23:04:53 -07:00
# not a flagging action, and haven't done it already
not ( is_flag || already_taken_this_action ) &&
2013-02-05 14:16:51 -05:00
2013-05-19 23:04:53 -07:00
# nothing except flagging on archived posts
not ( post . topic . archived? ) &&
2013-05-02 15:15:17 +10:00
2013-05-19 23:04:53 -07:00
# don't like your own stuff
not ( action_key == :like && is_my_own? ( post ) ) &&
2013-02-05 14:16:51 -05:00
2013-05-19 23:04:53 -07:00
# no voting more than once on single vote topics
not ( action_key == :vote && opts [ :voted_in_topic ] && post . topic . has_meta_data_boolean? ( :single_vote ) )
end
2013-02-05 14:16:51 -05:00
end
2013-04-29 16:33:24 +10:00
def secure_category_ids
2013-05-19 23:04:53 -07:00
@secure_category_ids || = @user . secure_category_ids
end
private
def is_my_own? ( obj )
@user . present? &&
( obj . respond_to? ( :user ) || obj . respond_to? ( :user_id ) ) &&
( obj . respond_to? ( :user ) ? obj . user == @user : true ) &&
( obj . respond_to? ( :user_id ) ? ( obj . user_id == @user . id ) : true )
end
def is_me? ( other )
other && authenticated? && User === other && @user == other
2013-04-29 16:33:24 +10:00
end
2013-05-19 23:04:53 -07:00
def is_not_me? ( other )
@user . blank? || ! is_me? ( other )
end
def can_administer? ( obj )
is_admin? && obj . present?
end
def can_administer_user? ( other_user )
can_administer? ( other_user ) && is_not_me? ( other_user )
end
def method_name_for ( action , obj )
method_name = :" can_ #{ action } _ #{ obj . class . name . underscore } ? "
return method_name if respond_to? ( method_name )
end
2013-02-05 14:16:51 -05:00
end