FEATURE: SSO support for adding and removing a user to groups

Use: add_groups with a comma delimited list to ensure a user is in groups (using group names)

Use: remove_groups with a comma delimited list to ensure a user is removed from groups (using group names)
This commit is contained in:
Sam 2016-11-11 16:57:31 +11:00
parent 01a8ef590a
commit 3d76ce1421
3 changed files with 64 additions and 1 deletions

View File

@ -94,11 +94,38 @@ class DiscourseSingleSignOn < SingleSignOn
sso_record.save! sso_record.save!
if sso_record.user
apply_group_rules(sso_record.user)
end
sso_record && sso_record.user sso_record && sso_record.user
end end
private private
def apply_group_rules(user)
if add_groups
split = add_groups.split(",")
if split.length > 0
Group.where('name in (?) AND NOT automatic', split).pluck(:id).each do |id|
unless GroupUser.where(group_id: id, user_id: user.id).exists?
GroupUser.create(group_id: id, user_id: user.id)
end
end
end
end
if remove_groups
split = remove_groups.split(",")
if split.length > 0
GroupUser
.where(user_id: user.id)
.where('group_id IN (SELECT id FROM groups WHERE name in (?))',split)
.destroy_all
end
end
end
def match_email_or_create_user(ip_address) def match_email_or_create_user(ip_address)
unless user = User.find_by_email(email) unless user = User.find_by_email(email)
try_name = name.presence try_name = name.presence

View File

@ -1,6 +1,7 @@
class SingleSignOn class SingleSignOn
ACCESSORS = [:nonce, :name, :username, :email, :avatar_url, :avatar_force_update, :require_activation, ACCESSORS = [:nonce, :name, :username, :email, :avatar_url, :avatar_force_update, :require_activation,
:bio, :external_id, :return_sso_url, :admin, :moderator, :suppress_welcome_message] :bio, :external_id, :return_sso_url, :admin, :moderator, :suppress_welcome_message,
:add_groups, :remove_groups]
FIXNUMS = [] FIXNUMS = []
BOOLS = [:avatar_force_update, :admin, :moderator, :require_activation, :suppress_welcome_message] BOOLS = [:avatar_force_update, :admin, :moderator, :require_activation, :suppress_welcome_message]
NONCE_EXPIRY_TIME = 10.minutes NONCE_EXPIRY_TIME = 10.minutes

View File

@ -113,6 +113,41 @@ describe DiscourseSingleSignOn do
expect(admin_group.users.where('users.id = ?', user.id).exists?).to eq(true) expect(admin_group.users.where('users.id = ?', user.id).exists?).to eq(true)
end end
it "can specify groups" do
user = Fabricate(:user)
add_group1 = Fabricate(:group, name: 'group1')
add_group2 = Fabricate(:group, name: 'group2')
existing_group = Fabricate(:group, name: 'group3')
existing_group.add(user)
existing_group.save!
add_group1.add(user)
existing_group.save!
sso = DiscourseSingleSignOn.new
sso.username = "bobsky"
sso.name = "Bob"
sso.email = user.email
sso.external_id = "A"
sso.add_groups = "#{add_group1.name},#{add_group2.name},badname"
sso.remove_groups = "#{existing_group.name},badname"
sso.lookup_or_create_user(ip_address)
existing_group.reload
expect(existing_group.usernames).to eq("")
add_group1.reload
expect(add_group1.usernames).to eq(user.username)
add_group2.reload
expect(add_group2.usernames).to eq(user.username)
end
it "can override name / email / username" do it "can override name / email / username" do
admin = Fabricate(:admin) admin = Fabricate(:admin)