FEATURE: initial implemenation of anonymous posting mode
This commit is contained in:
parent
cd5af46fb7
commit
f5d89169e2
|
@ -1,10 +1,24 @@
|
|||
export default Ember.ArrayController.extend({
|
||||
showAdminLinks: Em.computed.alias("currentUser.staff"),
|
||||
|
||||
allowAnon: function(){
|
||||
return Discourse.SiteSettings.allow_anonymous_posting &&
|
||||
Discourse.User.currentProp("trust_level") >= Discourse.SiteSettings.anonymous_posting_min_trust_level;
|
||||
}.property(),
|
||||
|
||||
isAnon: function(){
|
||||
return Discourse.User.currentProp("is_anonymous");
|
||||
}.property(),
|
||||
|
||||
actions: {
|
||||
logout() {
|
||||
Discourse.logout();
|
||||
return false;
|
||||
},
|
||||
toggleAnon() {
|
||||
Discourse.ajax("/users/toggle-anon", {method: 'POST'}).then(function(){
|
||||
window.location.reload();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
</li>
|
||||
<li>{{#link-to 'userActivity.bookmarks' currentUser}}{{i18n 'user.bookmarks'}}{{/link-to}}</li>
|
||||
<li>{{#link-to 'preferences' currentUser}}{{i18n 'user.preferences'}}{{/link-to}}</li>
|
||||
{{#if allowAnon}}
|
||||
<li><a href {{action toggleAnon}}>{{#if isAnon}}{{i18n 'switch_from_anon'}}{{else}}{{i18n 'switch_to_anon'}}{{/if}}</a></li>
|
||||
{{/if}}
|
||||
<li>{{d-button action="logout" class="btn-danger right logout" icon="sign-out" label="user.log_out"}}</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
|
|
@ -6,7 +6,7 @@ require_dependency 'rate_limiter'
|
|||
class UsersController < ApplicationController
|
||||
|
||||
skip_before_filter :authorize_mini_profiler, only: [:avatar]
|
||||
skip_before_filter :check_xhr, only: [:show, :password_reset, :update, :account_created, :activate_account, :perform_account_activation, :authorize_email, :user_preferences_redirect, :avatar, :my_redirect]
|
||||
skip_before_filter :check_xhr, only: [:show, :password_reset, :update, :account_created, :activate_account, :perform_account_activation, :authorize_email, :user_preferences_redirect, :avatar, :my_redirect, :toggle_anon]
|
||||
|
||||
before_filter :ensure_logged_in, only: [:username, :update, :change_email, :user_preferences_redirect, :upload_user_image, :pick_avatar, :destroy_user_image, :destroy, :check_emails]
|
||||
before_filter :respond_to_suspicious_request, only: [:create]
|
||||
|
@ -343,6 +343,18 @@ class UsersController < ApplicationController
|
|||
@success = I18n.t(message)
|
||||
end
|
||||
|
||||
def toggle_anon
|
||||
user = AnonymousShadowCreator.get_master(current_user) ||
|
||||
AnonymousShadowCreator.get(current_user)
|
||||
|
||||
if user
|
||||
log_on_user(user)
|
||||
render json: success_json
|
||||
else
|
||||
render json: failed_json, status: 403
|
||||
end
|
||||
end
|
||||
|
||||
def change_email
|
||||
params.require(:email)
|
||||
user = fetch_user_from_params
|
||||
|
|
|
@ -25,7 +25,8 @@ class CurrentUserSerializer < BasicUserSerializer
|
|||
:disable_jump_reply,
|
||||
:custom_fields,
|
||||
:muted_category_ids,
|
||||
:dismissed_banner_key
|
||||
:dismissed_banner_key,
|
||||
:is_anonymous
|
||||
|
||||
def include_site_flagged_posts_count?
|
||||
object.staff?
|
||||
|
@ -102,4 +103,10 @@ class CurrentUserSerializer < BasicUserSerializer
|
|||
object.user_profile.dismissed_banner_key
|
||||
end
|
||||
|
||||
def is_anonymous
|
||||
SiteSetting.allow_anonymous_posting &&
|
||||
object.trust_level >= 1 &&
|
||||
object.custom_fields["master_id"].to_i > 0
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
class AnonymousShadowCreator
|
||||
|
||||
def self.get_master(user)
|
||||
return unless user
|
||||
return if !SiteSetting.allow_anonymous_posting
|
||||
|
||||
if (master_id = user.custom_fields["master_id"].to_i) > 0
|
||||
User.find_by(id: master_id)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def self.get(user)
|
||||
return unless user
|
||||
return if !SiteSetting.allow_anonymous_posting ||
|
||||
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)
|
||||
else
|
||||
create_shadow(user)
|
||||
end
|
||||
end
|
||||
|
||||
def self.create_shadow(user)
|
||||
User.transaction do
|
||||
shadow = User.create!(
|
||||
password: SecureRandom.hex,
|
||||
email: "#{SecureRandom.hex}@#{SecureRandom.hex}.com",
|
||||
name: "",
|
||||
username: UserNameSuggester.suggest(I18n.t(:anonymous).downcase),
|
||||
active: true,
|
||||
trust_level: 1,
|
||||
trust_level_locked: true,
|
||||
email_private_messages: false,
|
||||
email_digests: false,
|
||||
created_at: user.created_at
|
||||
)
|
||||
|
||||
shadow.email_tokens.update_all confirmed: true
|
||||
shadow.activate
|
||||
|
||||
|
||||
UserCustomField.create!(user_id: user.id,
|
||||
name: "shadow_id",
|
||||
value: shadow.id)
|
||||
|
||||
UserCustomField.create!(user_id: shadow.id,
|
||||
name: "master_id",
|
||||
value: user.id)
|
||||
|
||||
shadow.reload
|
||||
user.reload
|
||||
|
||||
shadow
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -213,6 +213,9 @@ en:
|
|||
revert: "Revert"
|
||||
failed: "Failed"
|
||||
|
||||
switch_to_anon: "Anonymous Mode"
|
||||
switch_from_anon: "Exit Anonymous Mode"
|
||||
|
||||
banner:
|
||||
close: "Dismiss this banner."
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ en:
|
|||
|
||||
purge_reason: "Automatically deleted as abandoned, unactivated account"
|
||||
disable_remote_images_download_reason: "Remote images download was disabled because there wasn't enough disk space available."
|
||||
anonymous: "Anonymous"
|
||||
|
||||
errors: &errors
|
||||
format: ! '%{attribute} %{message}'
|
||||
|
@ -1088,6 +1089,8 @@ en:
|
|||
public_user_custom_fields: "A whitelist of custom fields for a user that can be shown publicly."
|
||||
staff_user_custom_fields: "A whitelist of custom fields for a user that can be shown to staff."
|
||||
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"
|
||||
|
||||
allow_profile_backgrounds: "Allow users to upload profile backgrounds."
|
||||
|
||||
|
|
|
@ -229,6 +229,7 @@ Discourse::Application.routes.draw do
|
|||
get "privacy" => "static#show", id: "privacy", as: 'privacy'
|
||||
get "signup" => "list#latest"
|
||||
|
||||
post "users/toggle-anon" => "users#toggle_anon"
|
||||
post "users/read-faq" => "users#read_faq"
|
||||
get "users/search/users" => "users#search_users"
|
||||
get "users/account-created/" => "users#account_created"
|
||||
|
|
|
@ -309,6 +309,12 @@ users:
|
|||
enable_user_directory:
|
||||
client: true
|
||||
default: true
|
||||
allow_anonymous_posting:
|
||||
default: false
|
||||
client: true
|
||||
anonymous_posting_min_trust_level:
|
||||
default: 1
|
||||
client: true
|
||||
|
||||
posting:
|
||||
min_post_length:
|
||||
|
|
|
@ -309,6 +309,25 @@ describe UsersController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#toggle_anon' do
|
||||
it 'allows you to toggle anon if enabled' do
|
||||
SiteSetting.allow_anonymous_posting = true
|
||||
|
||||
user = log_in
|
||||
user.trust_level = 1
|
||||
user.save
|
||||
|
||||
post :toggle_anon
|
||||
expect(response).to be_success
|
||||
expect(session[:current_user_id]).to eq(AnonymousShadowCreator.get(user).id)
|
||||
|
||||
post :toggle_anon
|
||||
expect(response).to be_success
|
||||
expect(session[:current_user_id]).to eq(user.id)
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
describe '#create' do
|
||||
|
||||
before do
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe AnonymousShadowCreator do
|
||||
|
||||
it "returns no shadow by default" do
|
||||
AnonymousShadowCreator.get(Fabricate.build(:user)).should == nil
|
||||
end
|
||||
|
||||
it "returns no shadow if trust level is not met" do
|
||||
SiteSetting.allow_anonymous_posting = true
|
||||
AnonymousShadowCreator.get(Fabricate.build(:user, trust_level: 0)).should == nil
|
||||
end
|
||||
|
||||
it "returns a shadow for a legit user" do
|
||||
SiteSetting.allow_anonymous_posting = true
|
||||
user = Fabricate(:user, trust_level: 3)
|
||||
|
||||
shadow = AnonymousShadowCreator.get(user)
|
||||
shadow2 = AnonymousShadowCreator.get(user)
|
||||
|
||||
shadow.id.should == shadow2.id
|
||||
|
||||
shadow.trust_level.should == 1
|
||||
|
||||
shadow.username.should == "anonymous"
|
||||
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue