2014-02-25 11:30:49 +08:00
|
|
|
require "spec_helper"
|
|
|
|
|
|
|
|
describe DiscourseSingleSignOn do
|
|
|
|
before do
|
|
|
|
@sso_url = "http://somesite.com/discourse_sso"
|
|
|
|
@sso_secret = "shjkfdhsfkjh"
|
|
|
|
|
2014-11-26 14:25:54 +08:00
|
|
|
SiteSetting.enable_sso = true
|
|
|
|
SiteSetting.sso_url = @sso_url
|
|
|
|
SiteSetting.sso_secret = @sso_secret
|
2014-02-25 11:30:49 +08:00
|
|
|
end
|
|
|
|
|
2014-03-20 05:14:09 +08:00
|
|
|
def make_sso
|
2014-02-25 11:30:49 +08:00
|
|
|
sso = SingleSignOn.new
|
|
|
|
sso.sso_url = "http://meta.discorse.org/topics/111"
|
|
|
|
sso.sso_secret = "supersecret"
|
|
|
|
sso.nonce = "testing"
|
|
|
|
sso.email = "some@email.com"
|
|
|
|
sso.username = "sam"
|
|
|
|
sso.name = "sam saffron"
|
|
|
|
sso.external_id = "100"
|
2015-05-21 21:41:36 +08:00
|
|
|
sso.require_activation = false
|
2014-04-22 11:52:13 +08:00
|
|
|
sso.custom_fields["a"] = "Aa"
|
|
|
|
sso.custom_fields["b.b"] = "B.b"
|
2014-03-20 05:14:09 +08:00
|
|
|
sso
|
|
|
|
end
|
2014-02-25 11:30:49 +08:00
|
|
|
|
2014-03-20 05:14:09 +08:00
|
|
|
def test_parsed(parsed, sso)
|
2014-12-31 22:55:03 +08:00
|
|
|
expect(parsed.nonce).to eq sso.nonce
|
|
|
|
expect(parsed.email).to eq sso.email
|
|
|
|
expect(parsed.username).to eq sso.username
|
|
|
|
expect(parsed.name).to eq sso.name
|
|
|
|
expect(parsed.external_id).to eq sso.external_id
|
2015-05-21 21:41:36 +08:00
|
|
|
expect(parsed.require_activation).to eq false
|
2014-12-31 22:55:03 +08:00
|
|
|
expect(parsed.custom_fields["a"]).to eq "Aa"
|
|
|
|
expect(parsed.custom_fields["b.b"]).to eq "B.b"
|
2014-03-20 05:14:09 +08:00
|
|
|
end
|
|
|
|
|
2014-12-29 10:30:54 +08:00
|
|
|
it "can do round trip parsing correctly" do
|
|
|
|
sso = SingleSignOn.new
|
|
|
|
sso.sso_secret = "test"
|
|
|
|
sso.name = "sam saffron"
|
|
|
|
sso.username = "sam"
|
|
|
|
sso.email = "sam@sam.com"
|
|
|
|
|
|
|
|
sso = SingleSignOn.parse(sso.payload, "test")
|
|
|
|
|
2014-12-31 22:55:03 +08:00
|
|
|
expect(sso.name).to eq "sam saffron"
|
|
|
|
expect(sso.username).to eq "sam"
|
|
|
|
expect(sso.email).to eq "sam@sam.com"
|
2014-12-29 10:30:54 +08:00
|
|
|
end
|
|
|
|
|
2015-02-24 04:58:45 +08:00
|
|
|
let(:ip_address) { "127.0.0.1" }
|
|
|
|
|
2014-06-02 15:32:39 +08:00
|
|
|
it "can lookup or create user when name is blank" do
|
|
|
|
# so we can create system messages
|
|
|
|
Fabricate(:admin)
|
|
|
|
sso = DiscourseSingleSignOn.new
|
|
|
|
sso.username = "test"
|
|
|
|
sso.name = ""
|
|
|
|
sso.email = "test@test.com"
|
|
|
|
sso.external_id = "A"
|
2015-02-24 04:58:45 +08:00
|
|
|
user = sso.lookup_or_create_user(ip_address)
|
2014-12-31 22:55:03 +08:00
|
|
|
expect(user).to_not be_nil
|
2014-06-02 15:32:39 +08:00
|
|
|
end
|
|
|
|
|
2015-03-27 06:39:35 +08:00
|
|
|
it "can override name / email / username" do
|
|
|
|
admin = Fabricate(:admin)
|
|
|
|
|
|
|
|
SiteSetting.sso_overrides_name = true
|
|
|
|
SiteSetting.sso_overrides_email = true
|
|
|
|
SiteSetting.sso_overrides_username = true
|
|
|
|
|
|
|
|
sso = DiscourseSingleSignOn.new
|
|
|
|
sso.username = "bob%the$admin"
|
|
|
|
sso.name = "Bob Admin"
|
|
|
|
sso.email = admin.email
|
|
|
|
sso.external_id = "A"
|
|
|
|
|
|
|
|
sso.lookup_or_create_user(ip_address)
|
|
|
|
|
|
|
|
admin.reload
|
|
|
|
|
|
|
|
expect(admin.name).to eq "Bob Admin"
|
|
|
|
expect(admin.username).to eq "bob_the_admin"
|
|
|
|
expect(admin.email).to eq admin.email
|
|
|
|
|
|
|
|
sso.email = "TEST@bob.com"
|
|
|
|
|
2015-03-27 07:25:32 +08:00
|
|
|
sso.name = "Louis C.K."
|
|
|
|
|
2015-03-27 06:39:35 +08:00
|
|
|
sso.lookup_or_create_user(ip_address)
|
|
|
|
|
|
|
|
admin.reload
|
2015-03-27 07:04:16 +08:00
|
|
|
|
2015-03-27 06:39:35 +08:00
|
|
|
expect(admin.email).to eq("test@bob.com")
|
2015-03-27 07:04:16 +08:00
|
|
|
expect(admin.username).to eq "bob_the_admin"
|
2015-03-27 07:25:32 +08:00
|
|
|
expect(admin.name).to eq "Louis C.K."
|
2015-03-27 06:39:35 +08:00
|
|
|
end
|
|
|
|
|
2014-03-20 05:14:09 +08:00
|
|
|
it "can fill in data on way back" do
|
|
|
|
sso = make_sso
|
|
|
|
|
|
|
|
url, payload = sso.to_url.split("?")
|
2014-12-31 22:55:03 +08:00
|
|
|
expect(url).to eq sso.sso_url
|
2014-03-20 05:14:09 +08:00
|
|
|
parsed = SingleSignOn.parse(payload, "supersecret")
|
|
|
|
|
|
|
|
test_parsed(parsed, sso)
|
|
|
|
end
|
|
|
|
|
|
|
|
it "handles sso_url with query params" do
|
|
|
|
sso = make_sso
|
|
|
|
sso.sso_url = "http://tcdev7.wpengine.com/?action=showlogin"
|
|
|
|
|
2014-12-31 22:55:03 +08:00
|
|
|
expect(sso.to_url.split('?').size).to eq 2
|
2014-03-20 05:14:09 +08:00
|
|
|
|
|
|
|
url, payload = sso.to_url.split("?")
|
2014-12-31 22:55:03 +08:00
|
|
|
expect(url).to eq "http://tcdev7.wpengine.com/"
|
2014-03-20 05:14:09 +08:00
|
|
|
parsed = SingleSignOn.parse(payload, "supersecret")
|
2014-02-25 11:30:49 +08:00
|
|
|
|
2014-03-20 05:14:09 +08:00
|
|
|
test_parsed(parsed, sso)
|
2014-02-25 11:30:49 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
it "validates nonce" do
|
|
|
|
_ , payload = DiscourseSingleSignOn.generate_url.split("?")
|
|
|
|
|
|
|
|
sso = DiscourseSingleSignOn.parse(payload)
|
2014-12-31 22:55:03 +08:00
|
|
|
expect(sso.nonce_valid?).to eq true
|
2014-02-25 11:30:49 +08:00
|
|
|
|
|
|
|
sso.expire_nonce!
|
|
|
|
|
2014-12-31 22:55:03 +08:00
|
|
|
expect(sso.nonce_valid?).to eq false
|
2014-02-25 11:30:49 +08:00
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
it "generates a correct sso url" do
|
|
|
|
|
|
|
|
url, payload = DiscourseSingleSignOn.generate_url.split("?")
|
2014-12-31 22:55:03 +08:00
|
|
|
expect(url).to eq @sso_url
|
2014-02-25 11:30:49 +08:00
|
|
|
|
|
|
|
sso = DiscourseSingleSignOn.parse(payload)
|
2014-12-31 22:55:03 +08:00
|
|
|
expect(sso.nonce).to_not be_nil
|
2014-02-25 11:30:49 +08:00
|
|
|
end
|
2015-01-28 23:47:59 +08:00
|
|
|
|
2015-05-16 01:00:34 +08:00
|
|
|
context 'trusting emails' do
|
|
|
|
let(:sso) {
|
|
|
|
sso = DiscourseSingleSignOn.new
|
|
|
|
sso.username = "test"
|
|
|
|
sso.name = "test"
|
|
|
|
sso.email = "test@example.com"
|
|
|
|
sso.external_id = "A"
|
|
|
|
sso
|
|
|
|
}
|
|
|
|
|
|
|
|
it 'activates users by default' do
|
|
|
|
user = sso.lookup_or_create_user(ip_address)
|
|
|
|
expect(user.active).to eq(true)
|
|
|
|
end
|
|
|
|
|
2015-05-20 00:16:02 +08:00
|
|
|
it 'does not activate user when asked not to' do
|
|
|
|
sso.require_activation = true
|
2015-05-16 01:00:34 +08:00
|
|
|
user = sso.lookup_or_create_user(ip_address)
|
|
|
|
expect(user.active).to eq(false)
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2015-03-21 01:03:24 +08:00
|
|
|
context 'welcome emails' do
|
|
|
|
let(:sso) {
|
|
|
|
sso = DiscourseSingleSignOn.new
|
|
|
|
sso.username = "test"
|
|
|
|
sso.name = "test"
|
|
|
|
sso.email = "test@example.com"
|
|
|
|
sso.external_id = "A"
|
|
|
|
sso
|
|
|
|
}
|
|
|
|
|
|
|
|
it "sends a welcome email by default" do
|
|
|
|
User.any_instance.expects(:enqueue_welcome_message).once
|
|
|
|
user = sso.lookup_or_create_user(ip_address)
|
|
|
|
end
|
|
|
|
|
|
|
|
it "suppresses the welcome email when asked to" do
|
|
|
|
User.any_instance.expects(:enqueue_welcome_message).never
|
|
|
|
sso.suppress_welcome_message = true
|
|
|
|
user = sso.lookup_or_create_user(ip_address)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-01-28 23:47:59 +08:00
|
|
|
context 'when sso_overrides_avatar is enabled' do
|
2015-01-29 00:52:07 +08:00
|
|
|
let!(:sso_record) { Fabricate(:single_sign_on_record, external_avatar_url: "http://example.com/an_image.png") }
|
|
|
|
let!(:sso) {
|
|
|
|
sso = DiscourseSingleSignOn.new
|
|
|
|
sso.username = "test"
|
|
|
|
sso.name = "test"
|
|
|
|
sso.email = sso_record.user.email
|
|
|
|
sso.external_id = sso_record.external_id
|
|
|
|
sso
|
|
|
|
}
|
|
|
|
let(:logo) { file_from_fixtures("logo.png") }
|
2015-01-28 23:47:59 +08:00
|
|
|
|
|
|
|
before do
|
|
|
|
SiteSetting.sso_overrides_avatar = true
|
|
|
|
end
|
|
|
|
|
|
|
|
it "deal with no avatar url passed for an existing user with an avatar" do
|
|
|
|
# Deliberately not setting avatar_url.
|
|
|
|
|
2015-02-24 04:58:45 +08:00
|
|
|
user = sso.lookup_or_create_user(ip_address)
|
2015-01-28 23:47:59 +08:00
|
|
|
expect(user).to_not be_nil
|
|
|
|
end
|
2015-01-29 00:52:07 +08:00
|
|
|
|
|
|
|
it "deal with no avatar_force_update passed as a boolean" do
|
|
|
|
FileHelper.stubs(:download).returns(logo)
|
|
|
|
|
|
|
|
sso.avatar_url = "http://example.com/a_different_image.png"
|
|
|
|
sso.avatar_force_update = true
|
|
|
|
|
2015-02-24 04:58:45 +08:00
|
|
|
user = sso.lookup_or_create_user(ip_address)
|
2015-01-29 00:52:07 +08:00
|
|
|
expect(user).to_not be_nil
|
|
|
|
end
|
2015-01-28 23:47:59 +08:00
|
|
|
end
|
2014-02-25 11:30:49 +08:00
|
|
|
end
|