Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Notify user on ability grant #1519

Merged
merged 7 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ def role_toggle

# Set/update ability
if new_value
@user.community_user.grant_privilege 'mod'
@user.community_user.grant_privilege! 'mod'
else
@user.community_user.privilege('mod').destroy
end
Expand Down Expand Up @@ -448,7 +448,7 @@ def mod_privilege_action
case params[:do]
when 'grant'
if ua.nil?
@user.community_user.grant_privilege(ability.internal_id)
@user.community_user.grant_privilege!(ability.internal_id)
AuditLog.admin_audit(event_type: 'ability_grant', related: @user, user: current_user,
comment: ability.internal_id.to_s)
elsif ua.is_suspended
Expand Down
33 changes: 29 additions & 4 deletions app/models/community_user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ class CommunityUser < ApplicationRecord

after_create :prevent_ulysses_case

delegate :url_helpers, to: 'Rails.application.routes'

def system?
user_id == -1
end
Expand Down Expand Up @@ -58,8 +60,6 @@ def flag_score
end
end

## Privilege functions

def privilege?(internal_id, ignore_suspension: false, ignore_mod: false)
if internal_id != 'mod' && !ignore_mod && user.is_moderator
return true # includes: privilege? 'mod'
Expand All @@ -77,11 +77,26 @@ def privilege(internal_id)
UserAbility.joins(:ability).where(community_user_id: id, abilities: { internal_id: internal_id }).first
end

def grant_privilege(internal_id)
##
# Grant a specified ability to this CommunityUser.
# @param internal_id [String] The +internal_id+ of the ability to grant.
# @param notify [Boolean] Whether to send a notification to the user.
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, host: community_host))
ArtOfCode- marked this conversation as resolved.
Show resolved Hide resolved
end
end

##
# Recalculate a specified ability for this CommunityUser. Will not revoke abilities that have already been granted.
# @param internal_id [String] The +internal_id+ of the ability to be recalculated.
# @param sandbox [Boolean] Whether to run in sandbox mode - if sandboxed, the ability will not be granted but the
# return value indicates whether it would have been.
# @return [Boolean] Whether or not the ability was granted.
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)
Expand All @@ -100,17 +115,27 @@ def recalc_privilege(internal_id, sandbox: false)
end

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

##
# Recalculate a list of standard abilities for this CommunityUser.
# @param sandbox [Boolean] Whether to run in sandbox mode - see {#recalc_privilege}.
# @return [Array<Boolean>]
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

alias ability? privilege?
alias ability privilege
alias grant_ability! grant_privilege!
alias recalc_ability recalc_privilege
alias recalc_abilities recalc_privileges

# 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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ class EnforceConcurrenceOfIsModeratorAndModAbility < ActiveRecord::Migration[5.2
def up
CommunityUser.unscoped.where(is_moderator: true).all.map do |cu|
RequestContext.community = cu.community
cu.grant_privilege 'mod'
cu.grant_privilege! 'mod'
end
end

Expand Down
6 changes: 3 additions & 3 deletions scripts/recalc_abilities.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@
puts "Scope: CommunityUser : #{cu.id}"
end

cu.recalc_privileges
cu.recalc_abilities

# Grant mod ability if mod status is given
if (cu.is_moderator || cu.is_admin || u.is_global_moderator || u.is_global_admin) && !cu.privilege?('mod')
cu.grant_privilege('mod')
if (cu.is_moderator || cu.is_admin || u.is_global_moderator || u.is_global_admin) && !cu.ability?('mod')
cu.grant_ability!('mod')
end

resolved << q.id
Expand Down
2 changes: 1 addition & 1 deletion scripts/recalc_abilities_upon_first_migration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
cu.recalc_privileges

if (cu.is_moderator || cu.is_admin || u.is_global_moderator || u.is_global_admin) && !cu.privilege?('mod')
cu.grant_privilege('mod')
cu.grant_privilege!('mod')
end
rescue
puts " !!! Error recalcing for CommunityUser.Id=#{cu.id}"
Expand Down
2 changes: 1 addition & 1 deletion test/models/user_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class UserTest < ActiveSupport::TestCase
assert_equal true, users(:moderator).can_update(post, post_type)
assert_equal true, users(:editor).can_update(post, post_type)

basic_user.community_user.grant_privilege('unrestricted')
basic_user.community_user.grant_privilege!('unrestricted')
assert_equal false, basic_user.can_update(post, post_type)
assert_equal true, basic_user.can_update(post, post_types(:free_edit))
end
Expand Down
Loading