Class: CommunityUser

Inherits:
ApplicationRecord show all
Defined in:
app/models/community_user.rb

Instance Method Summary collapse

Methods inherited from ApplicationRecord

#attributes_print, fuzzy_search, match_search, #match_search, sanitize_for_search, sanitize_name, sanitize_sql_in, useful_err_msg, with_lax_group_rules

Instance Method Details

#edit_scoreObject



49
50
51
52
53
54
55
56
# File 'app/models/community_user.rb', line 49

def edit_score
  Rails.cache.fetch("privileges/#{id}/edit_score", expires_in: 3.hours) do
    good_edits = SuggestedEdit.where(user: user).where(active: false, accepted: true).count
    bad_edits = SuggestedEdit.where(user: user).where(active: false, accepted: false).count

    (good_edits + 2.0) / (good_edits + bad_edits + 4.0)
  end
end

#flag_scoreObject



58
59
60
61
62
63
64
65
# File 'app/models/community_user.rb', line 58

def flag_score
  Rails.cache.fetch("privileges/#{id}/flag_score", expires_in: 3.hours) do
    good_flags = Flag.where(user: user).where(status: 'helpful').count
    bad_flags = Flag.where(user: user).where(status: 'declined').count

    (good_flags + 2.0) / (good_flags + bad_flags + 4.0)
  end
end

#grant_privilege!(internal_id, notify: true) ⇒ Object Also known as: grant_ability!

Grant a specified ability to this CommunityUser.

Parameters:

  • internal_id (String)

    The internal_id of the ability to grant.

  • notify (Boolean) (defaults to: true)

    Whether to send a notification to the user.



88
89
90
91
92
93
94
95
96
# File 'app/models/community_user.rb', line 88

def grant_privilege!(internal_id, notify: true)
  priv = Ability.where(internal_id: internal_id).first
  UserAbility.create community_user_id: id, ability: priv
  if notify
    community_host = priv.community.host
    user.create_notification("You've earned the #{priv.name} ability! Learn more.",
                             url_helpers.ability_url(priv.internal_id, host: community_host))
  end
end

#latest_warningObject



33
34
35
# File 'app/models/community_user.rb', line 33

def latest_warning
  mod_warnings&.order(created_at: 'desc')&.first&.created_at
end

#post_scoreObject

Calculation functions for privilege scores These are quite expensive, so we’ll cache them for a while



39
40
41
42
43
44
45
46
47
# File 'app/models/community_user.rb', line 39

def post_score
  Rails.cache.fetch("privileges/#{id}/post_score", expires_in: 3.hours) do
    exclude_types = ApplicationController.helpers.post_type_ids(is_freely_editable: true)
    good_posts = Post.where(user: user).where('score > 0.5').where.not(post_type_id: exclude_types).count
    bad_posts = Post.where(user: user).where('score < 0.5').where.not(post_type_id: exclude_types).count

    (good_posts + 2.0) / (good_posts + bad_posts + 4.0)
  end
end

#prevent_ulysses_caseObject

This check makes sure that every user gets the ‘everyone’ permission upon creation. We do not want to create a no permissions user by accident. Polyphemus is very grateful for this.



147
148
149
# File 'app/models/community_user.rb', line 147

def prevent_ulysses_case
  recalc_privileges
end

#privilege(internal_id) ⇒ Object Also known as: ability



80
81
82
# File 'app/models/community_user.rb', line 80

def privilege(internal_id)
  UserAbility.joins(:ability).where(community_user_id: id, abilities: { internal_id: internal_id }).first
end

#privilege?(internal_id, ignore_suspension: false, ignore_mod: false) ⇒ Boolean Also known as: ability?

Returns:

  • (Boolean)


67
68
69
70
71
72
73
74
75
76
77
78
# File 'app/models/community_user.rb', line 67

def privilege?(internal_id, ignore_suspension: false, ignore_mod: false)
  if internal_id != 'mod' && !ignore_mod && user.is_moderator
    return true # includes: privilege? 'mod'
  end

  up = privilege(internal_id)
  if ignore_suspension
    !up.nil?
  else
    !up.nil? && !up.suspended?
  end
end

#recalc_privilege(internal_id, sandbox: false) ⇒ Boolean Also known as: recalc_ability

Recalculate a specified ability for this CommunityUser. Will not revoke abilities that have already been granted.

Parameters:

  • internal_id (String)

    The internal_id of the ability to be recalculated.

  • sandbox (Boolean) (defaults to: false)

    Whether to run in sandbox mode - if sandboxed, the ability will not be granted but the return value indicates whether it would have been.

Returns:

  • (Boolean)

    Whether or not the ability was granted.



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'app/models/community_user.rb', line 104

def recalc_privilege(internal_id, sandbox: false)
  # Do not recalculate privileges already granted
  return true if privilege?(internal_id, ignore_suspension: true, ignore_mod: false)

  priv = Ability.where(internal_id: internal_id).first

  # Do not recalculate privileges which are only manually given
  return false if priv.manual?

  # Grant :unrestricted automatically on new communities
  unless SiteSetting['NewSiteMode'] && internal_id.to_s == 'unrestricted'
    # Abort if any of the checks fails
    return false if !priv.post_score_threshold.nil? && post_score < priv.post_score_threshold
    return false if !priv.edit_score_threshold.nil? && edit_score < priv.edit_score_threshold
    return false if !priv.flag_score_threshold.nil? && flag_score < priv.flag_score_threshold
  end

  # If not sandbox mode, create new privilege entry
  grant_privilege!(internal_id) unless sandbox
  recalc_trust_level unless sandbox
  true
end

#recalc_privileges(sandbox: false) ⇒ Array<Boolean> Also known as: recalc_abilities

Recalculate a list of standard abilities for this CommunityUser.

Parameters:

  • sandbox (Boolean) (defaults to: false)

    Whether to run in sandbox mode - see #recalc_privilege.

Returns:

  • (Array<Boolean>)


131
132
133
134
135
# File 'app/models/community_user.rb', line 131

def recalc_privileges(sandbox: false)
  [:everyone, :unrestricted, :edit_posts, :edit_tags, :flag_close, :flag_curate].map do |ability|
    recalc_privilege(ability, sandbox: sandbox)
  end
end

#recalc_trust_levelObject



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'app/models/community_user.rb', line 155

def recalc_trust_level
  trust = if user.staff?
            5
          elsif is_moderator || user.is_global_moderator || is_admin || user.is_global_admin
            4
          elsif privilege?('flag_close') || privilege?('edit_posts')
            3
          elsif privilege?('unrestricted')
            2
          else
            1
          end
  update(trust_level: trust)
  trust
end

#suspended?Boolean

Returns:

  • (Boolean)


23
24
25
26
27
28
29
30
31
# File 'app/models/community_user.rb', line 23

def suspended?
  return true if is_suspended && !suspension_end.past?

  if is_suspended
    update(is_suspended: false, suspension_public_comment: nil, suspension_end: nil)
  end

  false
end

#system?Boolean

Returns:

  • (Boolean)


19
20
21
# File 'app/models/community_user.rb', line 19

def system?
  user_id == -1
end

#trust_levelObject



151
152
153
# File 'app/models/community_user.rb', line 151

def trust_level
  attributes['trust_level'] || recalc_trust_level
end