automatic group infrustructure
This commit is contained in:
parent
93e9bcc7eb
commit
be1ab8b275
|
@ -63,30 +63,28 @@ class Admin::UsersController < Admin::AdminController
|
|||
def revoke_admin
|
||||
@admin = User.where(id: params[:user_id]).first
|
||||
guardian.ensure_can_revoke_admin!(@admin)
|
||||
@admin.update_column(:admin, false)
|
||||
@admin.revoke_admin!
|
||||
render nothing: true
|
||||
end
|
||||
|
||||
def grant_admin
|
||||
@user = User.where(id: params[:user_id]).first
|
||||
guardian.ensure_can_grant_admin!(@user)
|
||||
@user.update_column(:admin, true)
|
||||
@user.grant_admin!
|
||||
render_serialized(@user, AdminUserSerializer)
|
||||
end
|
||||
|
||||
def revoke_moderation
|
||||
@moderator = User.where(id: params[:user_id]).first
|
||||
guardian.ensure_can_revoke_moderation!(@moderator)
|
||||
@moderator.moderator = false
|
||||
@moderator.save
|
||||
@moderator.revoke_moderation!
|
||||
render nothing: true
|
||||
end
|
||||
|
||||
def grant_moderation
|
||||
@user = User.where(id: params[:user_id]).first
|
||||
guardian.ensure_can_grant_moderation!(@user)
|
||||
@user.moderator = true
|
||||
@user.save
|
||||
@user.grant_moderation!
|
||||
render_serialized(@user, AdminUserSerializer)
|
||||
end
|
||||
|
||||
|
|
|
@ -5,6 +5,88 @@ class Group < ActiveRecord::Base
|
|||
has_many :categories, through: :category_groups
|
||||
has_many :users, through: :group_users
|
||||
|
||||
AUTO_GROUPS = {
|
||||
:admins => 1,
|
||||
:moderators => 2,
|
||||
:staff => 3,
|
||||
:trust_level_1 => 11,
|
||||
:trust_level_2 => 12,
|
||||
:trust_level_3 => 13,
|
||||
:trust_level_4 => 14,
|
||||
:trust_level_5 => 15
|
||||
}
|
||||
|
||||
def self.trust_group_ids
|
||||
(10..19).to_a
|
||||
end
|
||||
|
||||
def self.refresh_automatic_group!(name)
|
||||
|
||||
id = AUTO_GROUPS[name]
|
||||
|
||||
unless group = self[name]
|
||||
group = Group.new(name: name.to_s, automatic: true)
|
||||
group.id = id
|
||||
group.save!
|
||||
end
|
||||
|
||||
|
||||
real_ids = case name
|
||||
when :admins
|
||||
"SELECT u.id FROM users u WHERE u.admin = 't'"
|
||||
when :moderators
|
||||
"SELECT u.id FROM users u WHERE u.moderator = 't'"
|
||||
when :staff
|
||||
"SELECT u.id FROM users u WHERE u.moderator = 't' OR u.admin = 't'"
|
||||
when :trust_level_1, :trust_level_2, :trust_level_3, :trust_level_4, :trust_level_5
|
||||
"SELECT u.id FROM users u WHERE u.trust_level = #{id-10}"
|
||||
end
|
||||
|
||||
|
||||
extra_users = group.users.where("users.id NOT IN (#{real_ids})").select('users.id')
|
||||
missing_users = GroupUser.joins("RIGHT JOIN (#{real_ids}) X ON X.id = user_id AND group_id = #{group.id}")
|
||||
.where("user_id IS NULL")
|
||||
.select("X.id")
|
||||
|
||||
group.group_users.where("user_id IN (#{extra_users.to_sql})").delete_all
|
||||
|
||||
missing_users.each do |u|
|
||||
group.group_users.build(user_id: u.id)
|
||||
end
|
||||
|
||||
group.save!
|
||||
end
|
||||
|
||||
def self.refresh_automatic_groups!(*args)
|
||||
args.each do |group|
|
||||
refresh_automatic_group!(group)
|
||||
end
|
||||
end
|
||||
|
||||
def self.[](name)
|
||||
raise ArgumentError, "unknown group" unless id = AUTO_GROUPS[name]
|
||||
|
||||
Group.where(id: id).first
|
||||
end
|
||||
|
||||
|
||||
def self.user_trust_level_change!(user_id, trust_level)
|
||||
name = "trust_level_#{trust_level}".to_sym
|
||||
|
||||
GroupUser.where(group_id: trust_group_ids, user_id: user_id).delete_all
|
||||
|
||||
if group = Group[name]
|
||||
group_users.build(user_id: user_id)
|
||||
group_users.save!
|
||||
else
|
||||
refresh_automatic_group!(name)
|
||||
end
|
||||
end
|
||||
|
||||
def user_ids
|
||||
users.select('users.id').map(&:id)
|
||||
end
|
||||
|
||||
def self.builtin
|
||||
Enum.new(:moderators, :admins, :trust_level_1, :trust_level_2)
|
||||
end
|
||||
|
|
|
@ -177,6 +177,34 @@ class User < ActiveRecord::Base
|
|||
where("username_lower = :user or lower(username) = :user or email = :email or lower(name) = :user", user: lower_user, email: lower_email)
|
||||
end
|
||||
|
||||
|
||||
def save_and_refresh_staff_groups!
|
||||
transaction do
|
||||
self.save!
|
||||
Group.refresh_automatic_groups!(:admins,:moderators,:staff)
|
||||
end
|
||||
end
|
||||
|
||||
def grant_moderation!
|
||||
self.moderator = true
|
||||
save_and_refresh_staff_groups!
|
||||
end
|
||||
|
||||
def revoke_moderation!
|
||||
self.moderator = false
|
||||
save_and_refresh_staff_groups!
|
||||
end
|
||||
|
||||
def grant_admin!
|
||||
self.admin = true
|
||||
save_and_refresh_staff_groups!
|
||||
end
|
||||
|
||||
def revoke_admin!
|
||||
self.admin = false
|
||||
save_and_refresh_staff_groups!
|
||||
end
|
||||
|
||||
def enqueue_welcome_message(message_type)
|
||||
return unless SiteSetting.send_welcome_message?
|
||||
Jobs.enqueue(:send_system_message, user_id: id, message_type: message_type)
|
||||
|
@ -439,9 +467,13 @@ class User < ActiveRecord::Base
|
|||
admin
|
||||
end
|
||||
|
||||
def change_trust_level(level)
|
||||
def change_trust_level!(level)
|
||||
raise "Invalid trust level #{level}" unless TrustLevel.valid_level?(level)
|
||||
self.trust_level = TrustLevel.levels[level]
|
||||
transaction do
|
||||
self.save!
|
||||
Group.user_trust_level_change!(self.id, self.trust_level)
|
||||
end
|
||||
end
|
||||
|
||||
def guardian
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
class AddAutomaticToGroups < ActiveRecord::Migration
|
||||
def up
|
||||
add_column :groups, :automatic, :boolean, default: false, null: false
|
||||
|
||||
# all numbers below 100 are reserved for automatic
|
||||
execute <<SQL
|
||||
ALTER SEQUENCE groups_id_seq START WITH 100
|
||||
SQL
|
||||
end
|
||||
|
||||
def down
|
||||
remove_column :groups, :automatic
|
||||
end
|
||||
end
|
|
@ -26,8 +26,7 @@ class Promotion
|
|||
return false if @user.posts_read_count < SiteSetting.basic_requires_read_posts
|
||||
return false if (@user.time_read / 60) < SiteSetting.basic_requires_time_spent_mins
|
||||
|
||||
@user.trust_level = TrustLevel.levels[:basic]
|
||||
@user.save
|
||||
@user.change_trust_level!(:basic)
|
||||
|
||||
true
|
||||
end
|
||||
|
@ -41,8 +40,7 @@ class Promotion
|
|||
return false if @user.likes_given < SiteSetting.regular_requires_likes_given
|
||||
return false if @user.topic_reply_count < SiteSetting.regular_requires_topic_reply_count
|
||||
|
||||
@user.trust_level = TrustLevel.levels[:regular]
|
||||
@user.save
|
||||
@user.change_trust_level!(:regular)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,4 +1,52 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Group do
|
||||
|
||||
it "Can update moderator/staff/admin groups correctly" do
|
||||
admin = Fabricate(:admin)
|
||||
moderator = Fabricate(:moderator)
|
||||
|
||||
Group.refresh_automatic_groups!(:admins, :staff, :moderators)
|
||||
|
||||
Group[:admins].user_ids.should == [admin.id]
|
||||
Group[:moderators].user_ids.should == [moderator.id]
|
||||
Group[:staff].user_ids.sort.should == [moderator.id,admin.id].sort
|
||||
|
||||
admin.admin = false
|
||||
admin.save
|
||||
|
||||
Group.refresh_automatic_group!(:admins)
|
||||
Group[:admins].user_ids.should == []
|
||||
|
||||
moderator.revoke_moderation!
|
||||
|
||||
admin.grant_admin!
|
||||
Group[:admins].user_ids.should == [admin.id]
|
||||
Group[:staff].user_ids.should == [admin.id]
|
||||
|
||||
admin.revoke_admin!
|
||||
Group[:admins].user_ids.should == []
|
||||
Group[:staff].user_ids.should == []
|
||||
|
||||
admin.grant_moderation!
|
||||
Group[:moderators].user_ids.should == [admin.id]
|
||||
Group[:staff].user_ids.should == [admin.id]
|
||||
|
||||
admin.revoke_moderation!
|
||||
Group[:admins].user_ids.should == []
|
||||
Group[:staff].user_ids.should == []
|
||||
end
|
||||
|
||||
it "Correctly updates automatic trust level groups" do
|
||||
user = Fabricate(:user)
|
||||
user.change_trust_level!(:basic)
|
||||
|
||||
Group[:trust_level_1].user_ids.should == [user.id]
|
||||
|
||||
user.change_trust_level!(:regular)
|
||||
|
||||
Group[:trust_level_1].user_ids.should == []
|
||||
Group[:trust_level_2].user_ids.should == [user.id]
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue