mirror of
https://github.com/codeninjasllc/discourse.git
synced 2025-03-23 05:15:45 -04:00
Merge pull request #1131 from novemberkilo/feature/temporary-boost-trust-levels
Feature: Admin can modify user trust levels
This commit is contained in:
commit
ea11286ab6
11 changed files with 186 additions and 3 deletions
app
assets/javascripts/admin
controllers/admin
config
lib
spec
|
@ -67,6 +67,37 @@ Discourse.AdminUser = Discourse.User.extend({
|
|||
return site.get('trust_levels').findProperty('id', this.get('trust_level'));
|
||||
}.property('trust_level'),
|
||||
|
||||
setOriginalTrustLevel: function() {
|
||||
this.set('originalTrustLevel', this.get('trust_level'));
|
||||
},
|
||||
|
||||
trustLevels: function() {
|
||||
var site = Discourse.Site.instance();
|
||||
return site.get('trust_levels');
|
||||
}.property('trust_level'),
|
||||
|
||||
dirty: function() {
|
||||
return this.get('originalTrustLevel') !== parseInt(this.get('trustLevel.id'), 10);
|
||||
}.property('originalTrustLevel', 'trustLevel.id'),
|
||||
|
||||
saveTrustLevel: function() {
|
||||
Discourse.ajax("/admin/users/" + this.id + "/trust_level", {
|
||||
type: 'PUT',
|
||||
data: {level: this.get('trustLevel.id')}
|
||||
}).then(function () {
|
||||
// succeeded
|
||||
window.location.reload();
|
||||
}, function(e) {
|
||||
// failure
|
||||
var error = Em.String.i18n('admin.user.trust_level_change_failed', { error: "http: " + e.status + " - " + e.body });
|
||||
bootbox.alert(error);
|
||||
});
|
||||
},
|
||||
|
||||
restoreTrustLevel: function() {
|
||||
this.set('trustLevel.id', this.get('originalTrustLevel'));
|
||||
},
|
||||
|
||||
isBanned: (function() {
|
||||
return this.get('is_banned') === true;
|
||||
}).property('is_banned'),
|
||||
|
|
|
@ -16,6 +16,11 @@ Discourse.AdminUserRoute = Discourse.Route.extend(Discourse.ModelReady, {
|
|||
return Discourse.AdminUser.find(Em.get(params, 'username').toLowerCase());
|
||||
},
|
||||
|
||||
setupController: function(controller, model) {
|
||||
controller.set('model', model);
|
||||
model.setOriginalTrustLevel();
|
||||
},
|
||||
|
||||
renderTemplate: function() {
|
||||
this.render({into: 'admin/templates/admin'});
|
||||
},
|
||||
|
|
|
@ -161,10 +161,22 @@
|
|||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class='display-row'>
|
||||
<div class='field'>{{i18n trust_level}}</div>
|
||||
<div class='value'>{{trustLevel.name}}</div>
|
||||
<div class="value">
|
||||
{{combobox content=trustLevels value=trustLevel.id }}
|
||||
</div>
|
||||
<div class="controls">
|
||||
{{#if dirty}}
|
||||
<div>
|
||||
<button class='btn ok' {{action saveTrustLevel target="content"}}><i class='icon-ok'></i></button>
|
||||
<button class='btn cancel' {{action restoreTrustLevel target="content"}}><i class='icon-remove'></i></button>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='display-row'>
|
||||
<div class='field'>{{i18n admin.user.banned}}</div>
|
||||
<div class='value'>{{isBanned}}</div>
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
require_dependency 'user_destroyer'
|
||||
require_dependency 'admin_user_index_query'
|
||||
require_dependency 'boost_trust_level'
|
||||
|
||||
class Admin::UsersController < Admin::AdminController
|
||||
|
||||
before_filter :fetch_user, only: [:ban, :unban, :refresh_browsers, :revoke_admin, :grant_admin, :revoke_moderation, :grant_moderation, :approve, :activate, :deactivate, :block, :unblock]
|
||||
before_filter :fetch_user, only: [:ban, :unban, :refresh_browsers, :revoke_admin, :grant_admin, :revoke_moderation, :grant_moderation, :approve, :activate, :deactivate, :block, :unblock, :trust_level]
|
||||
|
||||
def index
|
||||
query = ::AdminUserIndexQuery.new(params)
|
||||
|
@ -69,6 +70,12 @@ class Admin::UsersController < Admin::AdminController
|
|||
render_serialized(@user, AdminUserSerializer)
|
||||
end
|
||||
|
||||
def trust_level
|
||||
guardian.ensure_can_change_trust_level!(@user)
|
||||
BoostTrustLevel.new(@user, params[:level]).save!
|
||||
render_serialized(@user, AdminUserSerializer)
|
||||
end
|
||||
|
||||
def approve
|
||||
guardian.ensure_can_approve!(@user)
|
||||
@user.approve(current_user)
|
||||
|
|
|
@ -1207,7 +1207,7 @@ en:
|
|||
deactivate_explanation: "A deactivated user must re-validate their email."
|
||||
banned_explanation: "A banned user can't log in."
|
||||
block_explanation: "A blocked user can't post or start topics."
|
||||
|
||||
trust_level_change_failed: "There was a problem changing the user's trust level."
|
||||
|
||||
site_content:
|
||||
none: "Choose a type of content to begin editing."
|
||||
|
|
|
@ -134,6 +134,8 @@ en:
|
|||
title: "leader"
|
||||
elder:
|
||||
title: "elder"
|
||||
change_failed_explanation: "You attempted to demote %{user_name} to '%{new_trust_level}'. However their trust level is already '%{current_trust_level}'. %{user_name} will remain at '%{current_trust_level}'"
|
||||
|
||||
|
||||
rate_limiter:
|
||||
too_many_requests: "You're doing that too often. Please wait %{time_left} before trying again."
|
||||
|
|
|
@ -49,6 +49,7 @@ Discourse::Application.routes.draw do
|
|||
put 'deactivate'
|
||||
put 'block'
|
||||
put 'unblock'
|
||||
put 'trust_level'
|
||||
end
|
||||
|
||||
resources :impersonate, constraints: AdminConstraint.new
|
||||
|
|
40
lib/boost_trust_level.rb
Normal file
40
lib/boost_trust_level.rb
Normal file
|
@ -0,0 +1,40 @@
|
|||
require_dependency 'promotion'
|
||||
|
||||
class BoostTrustLevel
|
||||
|
||||
def initialize(user, level)
|
||||
@user = user
|
||||
@level = level.to_i
|
||||
@promotion = Promotion.new(@user)
|
||||
@trust_levels = TrustLevel.levels
|
||||
end
|
||||
|
||||
def save!
|
||||
if @level < @user.trust_level
|
||||
demote!
|
||||
else
|
||||
@user.update_attributes!(trust_level: @level)
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def demote!
|
||||
current_trust_level = @user.trust_level
|
||||
@user.update_attributes!(trust_level: @level)
|
||||
if @promotion.review
|
||||
@user.update_attributes!(trust_level: current_trust_level)
|
||||
raise Discourse::InvalidAccess.new, I18n.t('trust_levels.change_failed_explanation',
|
||||
user_name: @user.name,
|
||||
new_trust_level: trust_level_lookup(@level),
|
||||
current_trust_level: trust_level_lookup(current_trust_level))
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
def trust_level_lookup(level)
|
||||
@trust_levels.key(level).id2name
|
||||
end
|
||||
|
||||
end
|
|
@ -137,6 +137,10 @@ class Guardian
|
|||
user && is_staff?
|
||||
end
|
||||
|
||||
def can_change_trust_level?(user)
|
||||
can_administer?(user)
|
||||
end
|
||||
|
||||
def can_block_user?(user)
|
||||
user && is_staff? && not(user.staff?)
|
||||
end
|
||||
|
|
48
spec/components/boost_trust_level_spec.rb
Normal file
48
spec/components/boost_trust_level_spec.rb
Normal file
|
@ -0,0 +1,48 @@
|
|||
require 'spec_helper'
|
||||
require 'boost_trust_level'
|
||||
|
||||
describe BoostTrustLevel do
|
||||
|
||||
let(:user) { Fabricate(:user) }
|
||||
|
||||
it "should upgrade the trust level of a user" do
|
||||
boostr = BoostTrustLevel.new(user, TrustLevel.levels[:basic])
|
||||
boostr.save!.should be_true
|
||||
user.trust_level.should == TrustLevel.levels[:basic]
|
||||
end
|
||||
|
||||
describe "demotions" do
|
||||
before { user.update_attributes(trust_level: TrustLevel.levels[:newuser]) }
|
||||
|
||||
context "for a user that has not done the requisite things to attain their trust level" do
|
||||
|
||||
before do
|
||||
# scenario: admin mistakenly promotes user's trust level
|
||||
user.update_attributes(trust_level: TrustLevel.levels[:basic])
|
||||
end
|
||||
|
||||
it "should demote the user" do
|
||||
boostr = BoostTrustLevel.new(user, TrustLevel.levels[:newuser])
|
||||
boostr.save!.should be_true
|
||||
user.trust_level.should == TrustLevel.levels[:newuser]
|
||||
end
|
||||
end
|
||||
|
||||
context "for a user that has done the requisite things to attain their trust level" do
|
||||
|
||||
before do
|
||||
user.topics_entered = SiteSetting.basic_requires_topics_entered + 1
|
||||
user.posts_read_count = SiteSetting.basic_requires_read_posts + 1
|
||||
user.time_read = SiteSetting.basic_requires_time_spent_mins * 60
|
||||
user.save!
|
||||
user.update_attributes(trust_level: TrustLevel.levels[:basic])
|
||||
end
|
||||
|
||||
it "should not demote the user" do
|
||||
boostr = BoostTrustLevel.new(user, TrustLevel.levels[:newuser])
|
||||
expect { boostr.save! }.to raise_error(Discourse::InvalidAccess, "You attempted to demote #{user.name} to 'newuser'. However their trust level is already 'basic'. #{user.name} will remain at 'basic'")
|
||||
user.trust_level.should == TrustLevel.levels[:basic]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -120,6 +120,39 @@ describe Admin::UsersController do
|
|||
end
|
||||
end
|
||||
|
||||
context '.trust_level' do
|
||||
before do
|
||||
@another_user = Fabricate(:coding_horror)
|
||||
end
|
||||
|
||||
it "raises an error when the user doesn't have permission" do
|
||||
Guardian.any_instance.expects(:can_change_trust_level?).with(@another_user).returns(false)
|
||||
xhr :put, :trust_level, user_id: @another_user.id
|
||||
response.should be_forbidden
|
||||
end
|
||||
|
||||
it "returns a 404 if the username doesn't exist" do
|
||||
xhr :put, :trust_level, user_id: 123123
|
||||
response.should be_forbidden
|
||||
end
|
||||
|
||||
it "upgrades the user's trust level" do
|
||||
xhr :put, :trust_level, user_id: @another_user.id, level: 2
|
||||
@another_user.reload
|
||||
@another_user.trust_level.should == 2
|
||||
end
|
||||
|
||||
it "raises an error when demoting a user below their current trust level" do
|
||||
@another_user.topics_entered = SiteSetting.basic_requires_topics_entered + 1
|
||||
@another_user.posts_read_count = SiteSetting.basic_requires_read_posts + 1
|
||||
@another_user.time_read = SiteSetting.basic_requires_time_spent_mins * 60
|
||||
@another_user.save!
|
||||
@another_user.update_attributes(trust_level: TrustLevel.levels[:basic])
|
||||
xhr :put, :trust_level, user_id: @another_user.id, level: TrustLevel.levels[:newuser]
|
||||
response.should be_forbidden
|
||||
end
|
||||
end
|
||||
|
||||
describe '.revoke_moderation' do
|
||||
before do
|
||||
@moderator = Fabricate(:moderator)
|
||||
|
|
Loading…
Reference in a new issue