From 838597e188259731bb684c46dc10294c31b4f5f5 Mon Sep 17 00:00:00 2001 From: ArtOfCode- Date: Fri, 17 Jan 2025 16:50:57 +0000 Subject: [PATCH 1/7] Notify user on ability grant --- app/models/community_user.rb | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/app/models/community_user.rb b/app/models/community_user.rb index b1390fcf8..61a19e635 100644 --- a/app/models/community_user.rb +++ b/app/models/community_user.rb @@ -77,11 +77,21 @@ 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. + def grant_privilege!(internal_id) priv = Ability.where(internal_id: internal_id).first UserAbility.create community_user_id: id, ability: priv + user.create_notification("You've earned the #{priv.name} ability! Learn more.", ability_url(priv)) 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) @@ -100,11 +110,15 @@ 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] def recalc_privileges(sandbox: false) [:everyone, :unrestricted, :edit_posts, :edit_tags, :flag_close, :flag_curate].map do |ability| recalc_privilege(ability, sandbox: sandbox) From 65100a877485fe1299b4691ed6c34ac74c8dcb9e Mon Sep 17 00:00:00 2001 From: ArtOfCode- Date: Fri, 17 Jan 2025 16:51:33 +0000 Subject: [PATCH 2/7] Update references to grant_privilege! --- app/controllers/users_controller.rb | 4 ++-- ...829_enforce_concurrence_of_is_moderator_and_mod_ability.rb | 2 +- scripts/recalc_abilities.rb | 2 +- scripts/recalc_abilities_upon_first_migration.rb | 2 +- test/models/user_test.rb | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index e42d54886..bcd8aa87e 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -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 @@ -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 diff --git a/db/migrate/20200813132829_enforce_concurrence_of_is_moderator_and_mod_ability.rb b/db/migrate/20200813132829_enforce_concurrence_of_is_moderator_and_mod_ability.rb index d84fdcc33..606f724a9 100644 --- a/db/migrate/20200813132829_enforce_concurrence_of_is_moderator_and_mod_ability.rb +++ b/db/migrate/20200813132829_enforce_concurrence_of_is_moderator_and_mod_ability.rb @@ -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 diff --git a/scripts/recalc_abilities.rb b/scripts/recalc_abilities.rb index eeda78688..99131b425 100644 --- a/scripts/recalc_abilities.rb +++ b/scripts/recalc_abilities.rb @@ -40,7 +40,7 @@ # 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') + cu.grant_privilege!('mod') end resolved << q.id diff --git a/scripts/recalc_abilities_upon_first_migration.rb b/scripts/recalc_abilities_upon_first_migration.rb index 520144e65..32b3c48e4 100644 --- a/scripts/recalc_abilities_upon_first_migration.rb +++ b/scripts/recalc_abilities_upon_first_migration.rb @@ -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}" diff --git a/test/models/user_test.rb b/test/models/user_test.rb index e7ffe7800..9d8cfd64b 100644 --- a/test/models/user_test.rb +++ b/test/models/user_test.rb @@ -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 From 7d776b80b4266aaefb904f1bb37bd092517fffa0 Mon Sep 17 00:00:00 2001 From: ArtOfCode- Date: Fri, 17 Jan 2025 17:07:20 +0000 Subject: [PATCH 3/7] Add aliases and use them --- app/models/community_user.rb | 6 +++++- scripts/recalc_abilities.rb | 6 +++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/models/community_user.rb b/app/models/community_user.rb index 61a19e635..1bbac90f8 100644 --- a/app/models/community_user.rb +++ b/app/models/community_user.rb @@ -58,7 +58,11 @@ def flag_score end end - ## Privilege functions + alias ability? privilege? + alias ability privilege + alias grant_ability! grant_privilege! + alias recalc_ability recalc_privilege + alias recalc_abilities recalc_privileges def privilege?(internal_id, ignore_suspension: false, ignore_mod: false) if internal_id != 'mod' && !ignore_mod && user.is_moderator diff --git a/scripts/recalc_abilities.rb b/scripts/recalc_abilities.rb index 99131b425..17c99d4fd 100644 --- a/scripts/recalc_abilities.rb +++ b/scripts/recalc_abilities.rb @@ -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 From 4e6d2d32d6e459b7d0558405dd88ea728e3bc951 Mon Sep 17 00:00:00 2001 From: ArtOfCode- Date: Fri, 17 Jan 2025 17:12:53 +0000 Subject: [PATCH 4/7] Helps if you define the methods first --- app/models/community_user.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/models/community_user.rb b/app/models/community_user.rb index 1bbac90f8..307825275 100644 --- a/app/models/community_user.rb +++ b/app/models/community_user.rb @@ -58,12 +58,6 @@ def flag_score end end - alias ability? privilege? - alias ability privilege - alias grant_ability! grant_privilege! - alias recalc_ability recalc_privilege - alias recalc_abilities recalc_privileges - def privilege?(internal_id, ignore_suspension: false, ignore_mod: false) if internal_id != 'mod' && !ignore_mod && user.is_moderator return true # includes: privilege? 'mod' @@ -129,6 +123,12 @@ def recalc_privileges(sandbox: false) 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. From eb6547402ff6121332059a0bff236241fd26c146 Mon Sep 17 00:00:00 2001 From: ArtOfCode- Date: Fri, 17 Jan 2025 17:17:04 +0000 Subject: [PATCH 5/7] That's a helper --- app/models/community_user.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/community_user.rb b/app/models/community_user.rb index 307825275..05885b310 100644 --- a/app/models/community_user.rb +++ b/app/models/community_user.rb @@ -81,7 +81,7 @@ def privilege(internal_id) def grant_privilege!(internal_id) priv = Ability.where(internal_id: internal_id).first UserAbility.create community_user_id: id, ability: priv - user.create_notification("You've earned the #{priv.name} ability! Learn more.", ability_url(priv)) + user.create_notification("You've earned the #{priv.name} ability! Learn more.", helpers.ability_url(priv)) end ## From 823110bd7afbb86a7feb3f5ce6f862f9fcabf899 Mon Sep 17 00:00:00 2001 From: ArtOfCode- Date: Fri, 17 Jan 2025 17:30:41 +0000 Subject: [PATCH 6/7] Make the helper actually work and add option --- app/models/community_user.rb | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/app/models/community_user.rb b/app/models/community_user.rb index 05885b310..faf36a30c 100644 --- a/app/models/community_user.rb +++ b/app/models/community_user.rb @@ -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 @@ -78,10 +80,15 @@ def privilege(internal_id) ## # Grant a specified ability to this CommunityUser. # @param internal_id [String] The +internal_id+ of the ability to grant. - def grant_privilege!(internal_id) + # @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 - user.create_notification("You've earned the #{priv.name} ability! Learn more.", helpers.ability_url(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)) + end end ## From 36f9dfd9414baeb66dc96727664f05f9d3031bac Mon Sep 17 00:00:00 2001 From: ArtOfCode- Date: Fri, 17 Jan 2025 19:57:13 +0000 Subject: [PATCH 7/7] Update to use internal_id --- app/models/community_user.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/community_user.rb b/app/models/community_user.rb index faf36a30c..e81d1f579 100644 --- a/app/models/community_user.rb +++ b/app/models/community_user.rb @@ -87,7 +87,7 @@ def grant_privilege!(internal_id, notify: true) 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)) + url_helpers.ability_url(priv.internal_id, host: community_host)) end end