Adds grant and revoke moderation buttons so admins can make users moderators

This commit is contained in:
Ismael Abreu 2013-02-12 22:58:08 +00:00
parent 51473a95b4
commit 80bec6efc9
10 changed files with 163 additions and 4 deletions

View File

@ -17,6 +17,19 @@ window.Discourse.AdminUser = Discourse.Model.extend
@set('can_revoke_admin',true)
$.ajax "/admin/users/#{@get('id')}/grant_admin", type: 'PUT'
# Revoke the user's moderation access
revokeModeration: ->
@set('moderator',false)
@set('can_grant_moderation',true)
@set('can_revoke_moderation',false)
$.ajax "/admin/users/#{@get('id')}/revoke_moderation", type: 'PUT'
grantModeration: ->
@set('moderator',true)
@set('can_grant_moderation',false)
@set('can_revoke_moderation',true)
$.ajax "/admin/users/#{@get('id')}/grant_moderation", type: 'PUT'
refreshBrowsers: ->
$.ajax "/admin/users/#{@get('id')}/refresh_browsers",
type: 'POST'

View File

@ -84,6 +84,21 @@
<div class='display-row'>
<div class='field'>{{i18n admin.user.moderator}}</div>
<div class='value'>{{content.moderator}}</div>
<div class='controls'>
{{#if content.can_revoke_moderation}}
<button class='btn' {{action revokeModeration target="content"}}>
<i class='icon icon-eye-close'></i>
{{i18n admin.user.revoke_moderation}}
</button>
{{/if}}
{{#if content.can_grant_moderation}}
<button class='btn' {{action grantModeration target="content"}}>
<i class='icon icon-eye-open'></i>
{{i18n admin.user.grant_moderation}}
</button>
{{/if}}
</div>
</div>
<div class='display-row'>
<div class='field'>{{i18n trust_level}}</div>

View File

@ -63,6 +63,22 @@ class Admin::UsersController < Admin::AdminController
render_serialized(@user, AdminUserSerializer)
end
def revoke_moderation
@moderator = User.where(id: params[:user_id]).first
guardian.ensure_can_revoke_moderation!(@moderator)
@moderator.change_trust_level(:advanced)
@moderator.save
render nothing: true
end
def grant_moderation
@user = User.where(id: params[:user_id]).first
guardian.ensure_can_grant_moderation!(@user)
@user.change_trust_level(:moderator)
@user.save
render_serialized(@user, AdminUserSerializer)
end
def approve
@user = User.where(id: params[:user_id]).first
guardian.ensure_can_approve!(@user)

View File

@ -401,6 +401,11 @@ class User < ActiveRecord::Base
(self.trust_level || TrustLevel.Levels[:new]) >= TrustLevel.Levels[level]
end
def change_trust_level(level)
raise "Invalid trust level #{level}" unless TrustLevel.Levels.has_key?(level)
self.trust_level = TrustLevel.Levels[level]
end
def guardian
Guardian.new(self)
end

View File

@ -2,8 +2,10 @@ class AdminDetailedUserSerializer < AdminUserSerializer
attributes :moderator,
:can_grant_admin,
:can_impersonate,
:can_revoke_admin,
:can_grant_moderation,
:can_revoke_moderation,
:can_impersonate,
:like_count,
:post_count,
:flags_given_count,
@ -21,6 +23,14 @@ class AdminDetailedUserSerializer < AdminUserSerializer
scope.can_grant_admin?(object)
end
def can_revoke_moderation
scope.can_revoke_moderation?(object)
end
def can_grant_moderation
scope.can_grant_moderation?(object)
end
def can_delete_all_posts
scope.can_delete_all_posts?(object)
end

View File

@ -390,6 +390,8 @@ en:
impersonate: 'Impersonate'
revoke_admin: 'Revoke Admin'
grant_admin: 'Grant Admin'
revoke_moderation: 'Revoke Moderation'
grant_moderation: 'Grant Moderation'
basics: Basics
reputation: Reputation
permissions: Permissions

View File

@ -34,6 +34,8 @@ Discourse::Application.routes.draw do
put 'unban' => 'users#unban'
put 'revoke_admin' => 'users#revoke_admin'
put 'grant_admin' => 'users#grant_admin'
put 'revoke_moderation' => 'users#revoke_moderation'
put 'grant_moderation' => 'users#grant_moderation'
put 'approve' => 'users#approve'
post 'refresh_browsers' => 'users#refresh_browsers'
end

View File

@ -131,6 +131,23 @@ class Guardian
true
end
def can_revoke_moderation?(moderator)
return false unless @user.try(:admin?)
return false if moderator.blank?
return false if @user.id == moderator.id
return false unless moderator.trust_level == TrustLevel.Levels[:moderator]
true
end
def can_grant_moderation?(user)
return false unless @user.try(:admin?)
return false if user.blank?
return false if @user.id == user.id
return false if user.admin?
return false if user.has_trust_level?(:moderator)
true
end
# Can we see who acted on a post in a particular way?
def can_see_post_actors?(topic, post_action_type_id)
return false unless topic.present?

View File

@ -761,6 +761,46 @@ describe Guardian do
end
end
context 'can_grant_moderation?' do
it "wont allow a non logged in user to grant an moderator's access" do
Guardian.new.can_grant_moderation?(user).should be_false
end
it "wont allow a regular user to revoke an modearator's access" do
Guardian.new(user).can_grant_moderation?(moderator).should be_false
end
it 'wont allow an admin to grant their own access' do
Guardian.new(admin).can_grant_moderation?(admin).should be_false
end
it 'wont allow an admin to grant it to an already moderator' do
Guardian.new(admin).can_grant_moderation?(moderator).should be_false
end
it "allows an admin to grant a regular user access" do
Guardian.new(admin).can_grant_moderation?(user).should be_true
end
end
context 'can_revoke_moderation?' do
it "wont allow a non logged in user to revoke an moderator's access" do
Guardian.new.can_revoke_moderation?(moderator).should be_false
end
it "wont allow a regular user to revoke an moderator's access" do
Guardian.new(user).can_revoke_moderation?(moderator).should be_false
end
it 'wont allow an moderator to revoke their own moderator' do
Guardian.new(moderator).can_revoke_moderation?(moderator).should be_false
end
it "allows an admin to revoke a moderator's access" do
Guardian.new(admin).can_revoke_moderation?(moderator).should be_true
end
end
context "can_see_pending_invites_from?" do
it 'is false without a logged in user' do

View File

@ -111,8 +111,47 @@ describe Admin::UsersController do
end
end
describe '.revoke_moderation' do
before do
@moderator = Fabricate(:moderator)
end
it 'raises an error unless the user can revoke access' do
Guardian.any_instance.expects(:can_revoke_moderation?).with(@moderator).returns(false)
xhr :put, :revoke_moderation, user_id: @moderator.id
response.should be_forbidden
end
it 'updates the moderator flag' do
xhr :put, :revoke_moderation, user_id: @moderator.id
@moderator.reload
@moderator.has_trust_level?(:moderator).should_not be_true
end
end
context '.grant_moderation' 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_grant_moderation?).with(@another_user).returns(false)
xhr :put, :grant_moderation, user_id: @another_user.id
response.should be_forbidden
end
it "returns a 404 if the username doesn't exist" do
xhr :put, :grant_moderation, user_id: 123123
response.should be_forbidden
end
it 'updates the moderator flag' do
xhr :put, :grant_moderation, user_id: @another_user.id
@another_user.reload
@another_user.has_trust_level?(:moderator).should be_true
end
end
end
end
end