mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-27 09:36:19 -05:00
FEATURE: allow shipping bio markdown via SSO
- Also adds site setting for sso_overrides_bio to disable bio editing by end users
This commit is contained in:
parent
e79c216bc0
commit
9018de39ed
10 changed files with 78 additions and 7 deletions
|
@ -48,6 +48,12 @@ export default Ember.Controller.extend(CanCheckEmails, {
|
||||||
return this.siteSettings.enable_badges && hasTitleBadges;
|
return this.siteSettings.enable_badges && hasTitleBadges;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@computed("model.can_change_bio")
|
||||||
|
canChangeBio(canChangeBio)
|
||||||
|
{
|
||||||
|
return canChangeBio;
|
||||||
|
},
|
||||||
|
|
||||||
@computed()
|
@computed()
|
||||||
canChangePassword() {
|
canChangePassword() {
|
||||||
return !this.siteSettings.enable_sso && this.siteSettings.enable_local_logins;
|
return !this.siteSettings.enable_sso && this.siteSettings.enable_local_logins;
|
||||||
|
|
|
@ -130,12 +130,14 @@
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if canChangeBio}}
|
||||||
<div class="control-group pref-bio">
|
<div class="control-group pref-bio">
|
||||||
<label class="control-label">{{i18n 'user.bio'}}</label>
|
<label class="control-label">{{i18n 'user.bio'}}</label>
|
||||||
<div class="controls bio-composer">
|
<div class="controls bio-composer">
|
||||||
{{d-editor value=model.bio_raw}}
|
{{d-editor value=model.bio_raw}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
{{#each userFields as |uf|}}
|
{{#each userFields as |uf|}}
|
||||||
{{user-field field=uf.field value=uf.value}}
|
{{user-field field=uf.field value=uf.value}}
|
||||||
|
|
|
@ -82,6 +82,11 @@ class DiscourseSingleSignOn < SingleSignOn
|
||||||
# optionally save the user and sso_record if they have changed
|
# optionally save the user and sso_record if they have changed
|
||||||
user.save!
|
user.save!
|
||||||
|
|
||||||
|
if bio && (user.user_profile.bio_raw.blank? || SiteSetting.sso_overrides_bio)
|
||||||
|
user.user_profile.bio_raw = bio
|
||||||
|
user.user_profile.save!
|
||||||
|
end
|
||||||
|
|
||||||
unless admin.nil? && moderator.nil?
|
unless admin.nil? && moderator.nil?
|
||||||
Group.refresh_automatic_groups!(:admins, :moderators, :staff)
|
Group.refresh_automatic_groups!(:admins, :moderators, :staff)
|
||||||
end
|
end
|
||||||
|
|
|
@ -101,7 +101,8 @@ class UserSerializer < BasicUserSerializer
|
||||||
:card_image_badge,
|
:card_image_badge,
|
||||||
:card_image_badge_id,
|
:card_image_badge_id,
|
||||||
:muted_usernames,
|
:muted_usernames,
|
||||||
:mailing_list_posts_per_day
|
:mailing_list_posts_per_day,
|
||||||
|
:can_change_bio
|
||||||
|
|
||||||
untrusted_attributes :bio_raw,
|
untrusted_attributes :bio_raw,
|
||||||
:bio_cooked,
|
:bio_cooked,
|
||||||
|
@ -132,6 +133,10 @@ class UserSerializer < BasicUserSerializer
|
||||||
object.id && object.id == scope.user.try(:id)
|
object.id && object.id == scope.user.try(:id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def can_change_bio
|
||||||
|
!(SiteSetting.enable_sso && SiteSetting.sso_overrides_bio)
|
||||||
|
end
|
||||||
|
|
||||||
def card_badge
|
def card_badge
|
||||||
object.user_profile.card_image_badge
|
object.user_profile.card_image_badge
|
||||||
end
|
end
|
||||||
|
|
|
@ -45,7 +45,9 @@ class UserUpdater
|
||||||
user_profile.location = attributes.fetch(:location) { user_profile.location }
|
user_profile.location = attributes.fetch(:location) { user_profile.location }
|
||||||
user_profile.dismissed_banner_key = attributes[:dismissed_banner_key] if attributes[:dismissed_banner_key].present?
|
user_profile.dismissed_banner_key = attributes[:dismissed_banner_key] if attributes[:dismissed_banner_key].present?
|
||||||
user_profile.website = format_url(attributes.fetch(:website) { user_profile.website })
|
user_profile.website = format_url(attributes.fetch(:website) { user_profile.website })
|
||||||
|
unless SiteSetting.enable_sso && SiteSetting.sso_overrides_bio
|
||||||
user_profile.bio_raw = attributes.fetch(:bio_raw) { user_profile.bio_raw }
|
user_profile.bio_raw = attributes.fetch(:bio_raw) { user_profile.bio_raw }
|
||||||
|
end
|
||||||
user_profile.profile_background = attributes.fetch(:profile_background) { user_profile.profile_background }
|
user_profile.profile_background = attributes.fetch(:profile_background) { user_profile.profile_background }
|
||||||
user_profile.card_background = attributes.fetch(:card_background) { user_profile.card_background }
|
user_profile.card_background = attributes.fetch(:card_background) { user_profile.card_background }
|
||||||
|
|
||||||
|
|
|
@ -977,6 +977,7 @@ en:
|
||||||
enable_sso_provider: "Implement Discourse SSO provider protocol at the /session/sso_provider endpoint, requires sso_secret to be set"
|
enable_sso_provider: "Implement Discourse SSO provider protocol at the /session/sso_provider endpoint, requires sso_secret to be set"
|
||||||
sso_url: "URL of single sign on endpoint (must include http:// or https://)"
|
sso_url: "URL of single sign on endpoint (must include http:// or https://)"
|
||||||
sso_secret: "Secret string used to cryptographically authenticate SSO information, be sure it is 10 characters or longer"
|
sso_secret: "Secret string used to cryptographically authenticate SSO information, be sure it is 10 characters or longer"
|
||||||
|
sso_overrides_bio: "Overrides user bio in user profile and prevents user from changing it"
|
||||||
sso_overrides_email: "Overrides local email with external site email from SSO payload on every login, and prevent local changes. (WARNING: discrepancies can occur due to normalization of local emails)"
|
sso_overrides_email: "Overrides local email with external site email from SSO payload on every login, and prevent local changes. (WARNING: discrepancies can occur due to normalization of local emails)"
|
||||||
sso_overrides_username: "Overrides local username with external site username from SSO payload on every login, and prevent local changes. (WARNING: discrepancies can occur due to differences in username length/requirements)"
|
sso_overrides_username: "Overrides local username with external site username from SSO payload on every login, and prevent local changes. (WARNING: discrepancies can occur due to differences in username length/requirements)"
|
||||||
sso_overrides_name: "Overrides local full name with external site full name from SSO payload on every login, and prevent local changes."
|
sso_overrides_name: "Overrides local full name with external site full name from SSO payload on every login, and prevent local changes."
|
||||||
|
|
|
@ -288,6 +288,7 @@ login:
|
||||||
default: ''
|
default: ''
|
||||||
regex: '^https?:\/\/.+[^\/]$'
|
regex: '^https?:\/\/.+[^\/]$'
|
||||||
sso_secret: ''
|
sso_secret: ''
|
||||||
|
sso_overrides_bio: false
|
||||||
sso_overrides_email: false
|
sso_overrides_email: false
|
||||||
sso_overrides_username: false
|
sso_overrides_username: false
|
||||||
sso_overrides_name: false
|
sso_overrides_name: false
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
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,
|
||||||
:about_me, :external_id, :return_sso_url, :admin, :moderator, :suppress_welcome_message]
|
:bio, :external_id, :return_sso_url, :admin, :moderator, :suppress_welcome_message]
|
||||||
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
|
||||||
|
|
|
@ -222,6 +222,47 @@ describe DiscourseSingleSignOn do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'setting bio for a user' do
|
||||||
|
let(:sso) {
|
||||||
|
sso = DiscourseSingleSignOn.new
|
||||||
|
sso.username = "test"
|
||||||
|
sso.name = "test"
|
||||||
|
sso.email = "test@test.com"
|
||||||
|
sso.external_id = "100"
|
||||||
|
sso.bio = "This **is** the bio"
|
||||||
|
sso
|
||||||
|
}
|
||||||
|
|
||||||
|
it 'can set bio if supplied on new users or users with empty bio' do
|
||||||
|
# new account
|
||||||
|
user = sso.lookup_or_create_user(ip_address)
|
||||||
|
expect(user.user_profile.bio_cooked).to match_html("<p>This <strong>is</strong> the bio</p>")
|
||||||
|
|
||||||
|
|
||||||
|
# no override by default
|
||||||
|
sso.bio = "new profile"
|
||||||
|
user = sso.lookup_or_create_user(ip_address)
|
||||||
|
|
||||||
|
expect(user.user_profile.bio_cooked).to match_html("<p>This <strong>is</strong> the bio</p>")
|
||||||
|
|
||||||
|
# yes override for blank
|
||||||
|
user.user_profile.bio_raw = " "
|
||||||
|
user.user_profile.save!
|
||||||
|
|
||||||
|
user = sso.lookup_or_create_user(ip_address)
|
||||||
|
expect(user.user_profile.bio_cooked).to match_html("<p>new profile</p>")
|
||||||
|
|
||||||
|
|
||||||
|
# yes override if site setting
|
||||||
|
sso.bio = "new profile 2"
|
||||||
|
SiteSetting.sso_overrides_bio = true
|
||||||
|
|
||||||
|
user = sso.lookup_or_create_user(ip_address)
|
||||||
|
expect(user.user_profile.bio_cooked).to match_html("<p>new profile 2</p>")
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
context 'when sso_overrides_avatar is enabled' do
|
context 'when sso_overrides_avatar is enabled' do
|
||||||
let!(:sso_record) { Fabricate(:single_sign_on_record, external_avatar_url: "http://example.com/an_image.png") }
|
let!(:sso_record) { Fabricate(:single_sign_on_record, external_avatar_url: "http://example.com/an_image.png") }
|
||||||
let!(:sso) {
|
let!(:sso) {
|
||||||
|
|
|
@ -65,7 +65,7 @@ describe UserUpdater do
|
||||||
user = Fabricate(:user)
|
user = Fabricate(:user)
|
||||||
updater = UserUpdater.new(acting_user, user)
|
updater = UserUpdater.new(acting_user, user)
|
||||||
|
|
||||||
updater.update(bio_raw: 'my new bio',
|
val = updater.update(bio_raw: 'my new bio',
|
||||||
email_always: 'true',
|
email_always: 'true',
|
||||||
mailing_list_mode: true,
|
mailing_list_mode: true,
|
||||||
digest_after_minutes: "45",
|
digest_after_minutes: "45",
|
||||||
|
@ -73,6 +73,8 @@ describe UserUpdater do
|
||||||
auto_track_topics_after_msecs: 101,
|
auto_track_topics_after_msecs: 101,
|
||||||
email_in_reply_to: false
|
email_in_reply_to: false
|
||||||
)
|
)
|
||||||
|
expect(val).to be_truthy
|
||||||
|
|
||||||
user.reload
|
user.reload
|
||||||
|
|
||||||
expect(user.user_profile.bio_raw).to eq 'my new bio'
|
expect(user.user_profile.bio_raw).to eq 'my new bio'
|
||||||
|
@ -84,12 +86,18 @@ describe UserUpdater do
|
||||||
expect(user.user_option.email_in_reply_to).to eq false
|
expect(user.user_option.email_in_reply_to).to eq false
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when update succeeds' do
|
context 'when sso overrides bio' do
|
||||||
it 'returns true' do
|
it 'does not change bio' do
|
||||||
|
SiteSetting.enable_sso = true
|
||||||
|
SiteSetting.sso_overrides_bio = true
|
||||||
|
|
||||||
user = Fabricate(:user)
|
user = Fabricate(:user)
|
||||||
updater = UserUpdater.new(acting_user, user)
|
updater = UserUpdater.new(acting_user, user)
|
||||||
|
|
||||||
expect(updater.update).to be_truthy
|
expect(updater.update(bio_raw: "new bio")).to be_truthy
|
||||||
|
|
||||||
|
user.reload
|
||||||
|
expect(user.user_profile.bio_raw).not_to eq 'new bio'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue