From 4bfca12b1168816e922b099ee72afa92cb4aa73c Mon Sep 17 00:00:00 2001 From: Sam <sam.saffron@gmail.com> Date: Wed, 8 Apr 2015 12:29:43 +1000 Subject: [PATCH] FEATURE: anonymous_account_duration_minutes , cycle anon accounts after N minutes from last post fixes it so anon users can not like stuff --- app/models/user.rb | 6 ++++ app/serializers/current_user_serializer.rb | 4 +-- app/services/anonymous_shadow_creator.rb | 15 ++++++++-- config/locales/server.en.yml | 1 + config/site_settings.yml | 2 ++ lib/guardian/post_guardian.rb | 4 ++- .../services/anonymous_shadow_creator_spec.rb | 30 ++++++++++++++++++- 7 files changed, 55 insertions(+), 7 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 6a8eea014..62604333f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -725,6 +725,12 @@ class User < ActiveRecord::Base UserProfile.create(user_id: id) end + def anonymous? + SiteSetting.allow_anonymous_posting && + trust_level >= 1 && + custom_fields["master_id"].to_i > 0 + end + protected def badge_grant diff --git a/app/serializers/current_user_serializer.rb b/app/serializers/current_user_serializer.rb index 83e1f57c3..e8b3e717a 100644 --- a/app/serializers/current_user_serializer.rb +++ b/app/serializers/current_user_serializer.rb @@ -104,9 +104,7 @@ class CurrentUserSerializer < BasicUserSerializer end def is_anonymous - SiteSetting.allow_anonymous_posting && - object.trust_level >= 1 && - object.custom_fields["master_id"].to_i > 0 + object.anonymous? end end diff --git a/app/services/anonymous_shadow_creator.rb b/app/services/anonymous_shadow_creator.rb index 0fb66ad15..3441455d8 100644 --- a/app/services/anonymous_shadow_creator.rb +++ b/app/services/anonymous_shadow_creator.rb @@ -16,7 +16,14 @@ class AnonymousShadowCreator user.trust_level < SiteSetting.anonymous_posting_min_trust_level if (shadow_id = user.custom_fields["shadow_id"].to_i) > 0 - User.find_by(id: shadow_id) || create_shadow(user) + shadow = User.find_by(id: shadow_id) + + if shadow && shadow.post_count > 0 && + shadow.last_posted_at < SiteSetting.anonymous_account_duration_minutes.minutes.ago + shadow = nil + end + + shadow || create_shadow(user) else create_shadow(user) end @@ -34,13 +41,17 @@ class AnonymousShadowCreator trust_level_locked: true, email_private_messages: false, email_digests: false, - created_at: user.created_at + created_at: 1.day.ago # bypass new user restrictions ) shadow.email_tokens.update_all confirmed: true shadow.activate + # can not hold dupes + UserCustomField.where(user_id: user.id, + name: "shadow_id").destroy_all + UserCustomField.create!(user_id: user.id, name: "shadow_id", value: shadow.id) diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 8605c2257..30b1c8dd8 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -1091,6 +1091,7 @@ en: enable_user_directory: "Provide a directory of users for browsing" allow_anonymous_posting: "Allow users to switch to anonymous mode" anonymous_posting_min_trust_level: "Minimum trust level required to enable anonymous posting" + anonymous_account_duration_minutes: "To protect anonymity create a new anonymous account every N minutes for each user. Example: if set to 600, as soon as 600 minutes elapse from last post AND user switches to anon, a new anonymous account is created." allow_profile_backgrounds: "Allow users to upload profile backgrounds." diff --git a/config/site_settings.yml b/config/site_settings.yml index 48fc75187..f7ccfda3c 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -315,6 +315,8 @@ users: anonymous_posting_min_trust_level: default: 1 client: true + anonymous_account_duration_minutes: + default: 10080 posting: min_post_length: diff --git a/lib/guardian/post_guardian.rb b/lib/guardian/post_guardian.rb index 4e6c57954..2e8031be7 100644 --- a/lib/guardian/post_guardian.rb +++ b/lib/guardian/post_guardian.rb @@ -8,7 +8,7 @@ module PostGuardian already_taken_this_action = taken.any? && taken.include?(PostActionType.types[action_key]) already_did_flagging = taken.any? && (taken & PostActionType.flag_types.values).any? - if authenticated? && post + result = if authenticated? && post && !@user.anonymous? return false if action_key == :notify_moderators && !SiteSetting.enable_private_messages @@ -37,6 +37,8 @@ module PostGuardian # 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 + + !!result end def can_defer_flags?(post) diff --git a/spec/services/anonymous_shadow_creator_spec.rb b/spec/services/anonymous_shadow_creator_spec.rb index 2735f44af..1c6b58c1d 100644 --- a/spec/services/anonymous_shadow_creator_spec.rb +++ b/spec/services/anonymous_shadow_creator_spec.rb @@ -11,6 +11,26 @@ describe AnonymousShadowCreator do AnonymousShadowCreator.get(Fabricate.build(:user, trust_level: 0)).should == nil end + it "returns a new shadow once time expires" do + SiteSetting.allow_anonymous_posting = true + SiteSetting.anonymous_account_duration_minutes = 1 + + user = Fabricate(:user, trust_level: 3) + shadow = AnonymousShadowCreator.get(user) + + freeze_time 2.minutes.from_now + shadow2 = AnonymousShadowCreator.get(user) + + shadow.id.should == shadow2.id + create_post(user: shadow) + + freeze_time 4.minutes.from_now + shadow3 = AnonymousShadowCreator.get(user) + + shadow2.id.should_not == shadow3.id + + end + it "returns a shadow for a legit user" do SiteSetting.allow_anonymous_posting = true user = Fabricate(:user, trust_level: 3) @@ -21,9 +41,17 @@ describe AnonymousShadowCreator do shadow.id.should == shadow2.id shadow.trust_level.should == 1 - shadow.username.should == "anonymous" + shadow.created_at.should_not == user.created_at + + + p = create_post + Guardian.new(shadow).post_can_act?(p, :like).should == false + Guardian.new(user).post_can_act?(p, :like).should == true + + user.anonymous?.should == false + shadow.anonymous?.should == true end end