Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • depau/discourse-saml
  • jackv/discourse-saml
2 results
Show changes
Commits on Source (2)
...@@ -40,11 +40,11 @@ class SamlAuthenticator < ::Auth::ManagedAuthenticator ...@@ -40,11 +40,11 @@ class SamlAuthenticator < ::Auth::ManagedAuthenticator
statements statements
.split("|") .split("|")
.map do |statement| .map do |statement|
attrs = statement.split(":", 2) attrs = statement.split(":", 2)
next if attrs.count != 2 next if attrs.count != 2
(result[attrs[0]] ||= []) << attrs[1].split(",") (result[attrs[0]] ||= []) << attrs[1].split(",")
result[attrs[0]].flatten! result[attrs[0]].flatten!
end end
result result
end end
...@@ -78,7 +78,7 @@ class SamlAuthenticator < ::Auth::ManagedAuthenticator ...@@ -78,7 +78,7 @@ class SamlAuthenticator < ::Auth::ManagedAuthenticator
want_assertions_signed: !!setting(:want_assertions_signed), want_assertions_signed: !!setting(:want_assertions_signed),
logout_requests_signed: !!setting(:logout_requests_signed), logout_requests_signed: !!setting(:logout_requests_signed),
logout_responses_signed: !!setting(:logout_responses_signed), logout_responses_signed: !!setting(:logout_responses_signed),
signature_method: XMLSecurity::Document::RSA_SHA1, signature_method: XMLSecurity::Document::RSA_SHA256,
}, },
idp_slo_session_destroy: idp_slo_session_destroy:
proc do |env, session| proc do |env, session|
...@@ -91,9 +91,28 @@ class SamlAuthenticator < ::Auth::ManagedAuthenticator ...@@ -91,9 +91,28 @@ class SamlAuthenticator < ::Auth::ManagedAuthenticator
) )
end end
# Only match by the NameID
def match_by_email
false
end
def match_by_username
false
end
def is_anonymous?(email)
email.start_with?("anonymous+") && email.end_with?("@rev.ng")
end
def primary_email_verified?(auth_token) def primary_email_verified?(auth_token)
attributes = OneLogin::RubySaml::Attributes.new(auth_token.extra&.[](:raw_info) || {}) attributes = OneLogin::RubySaml::Attributes.new(auth_token.extra&.[](:raw_info) || {})
email = attributes.single("email")
return false if is_anonymous?(email)
email_verified = attributes.single("emailVerified")
return email_verified == "true" if attributes.include?("emailVerified")
group_attribute = setting(:groups_attribute) group_attribute = setting(:groups_attribute)
if setting(:validate_email_fields).present? && attributes.multi(group_attribute).present? if setting(:validate_email_fields).present? && attributes.multi(group_attribute).present?
validate_email_fields = setting(:validate_email_fields).split("|").map(&:downcase) validate_email_fields = setting(:validate_email_fields).split("|").map(&:downcase)
...@@ -110,12 +129,16 @@ class SamlAuthenticator < ::Auth::ManagedAuthenticator ...@@ -110,12 +129,16 @@ class SamlAuthenticator < ::Auth::ManagedAuthenticator
extra_data = auth.extra || {} extra_data = auth.extra || {}
attributes = extra_data[:raw_info] || OneLogin::RubySaml::Attributes.new attributes = extra_data[:raw_info] || OneLogin::RubySaml::Attributes.new
log("after_authenticate: auth: #{auth.inspect}")
log("after_authenticate: attributes: #{attributes.inspect}")
log("after_authenticate: extra_data: #{extra_data.inspect}")
log("after_authenticate: uid: #{attributes.single("uid")}, #{auth[:uid]}")
auth[:uid] = attributes.single("uid") || auth[:uid] if setting(:use_attributes_uid) auth[:uid] = attributes.single("uid") || auth[:uid] if setting(:use_attributes_uid)
uid = auth[:uid] uid = auth[:uid]
auth.info[:email] ||= uid if uid.to_s&.include?("@") auth.info[:username] = attributes.single("username")
auth.info[:nickname] = attributes.single("username")
auth.info[:nickname] = uid.to_s if uid && setting(:use_attributes_uid)
auth.extra = { "raw_info" => attributes.attributes } auth.extra = { "raw_info" => attributes.attributes }
result = super result = super
...@@ -133,22 +156,31 @@ class SamlAuthenticator < ::Auth::ManagedAuthenticator ...@@ -133,22 +156,31 @@ class SamlAuthenticator < ::Auth::ManagedAuthenticator
result.skip_email_validation = true if setting(:skip_email_validation) result.skip_email_validation = true if setting(:skip_email_validation)
if result.user.blank? email = attributes.single("email")
result.username = "" if setting(:clear_username)
result.user = auto_create_account(result, uid) if setting(:auto_create_account) && if not is_anonymous?(email)
result.email_valid if result.user.blank?
result.username = "" if setting(:clear_username)
result.user = auto_create_account(result, uid) if setting(:auto_create_account) &&
result.email_valid
else
user = result.user
sync_groups(user, attributes, info)
sync_custom_fields(user, attributes, info)
sync_moderator(user, attributes)
sync_admin(user, attributes)
sync_trust_level(user, attributes)
sync_locale(user, attributes)
end
else else
user = result.user result.failed = true
sync_groups(user, attributes, info) result.failed_reason = "Anonymous users cannot access Discourse. " +
sync_custom_fields(user, attributes, info) "Convert your account to a regular account to continue."
sync_moderator(user, attributes)
sync_admin(user, attributes)
sync_trust_level(user, attributes)
sync_locale(user, attributes)
end end
result.overrides_username = setting(:omit_username) result.overrides_username = setting(:omit_username)
result.overrides_email = setting(:sync_email) result.overrides_email = setting(:sync_email)
result.overrides_name = true
result result
end end
...@@ -267,19 +299,19 @@ class SamlAuthenticator < ::Auth::ManagedAuthenticator ...@@ -267,19 +299,19 @@ class SamlAuthenticator < ::Auth::ManagedAuthenticator
statements statements
.split("|") .split("|")
.each do |statement| .each do |statement|
key, field_id = statement.split(":") key, field_id = statement.split(":")
next if key.blank? || field_id.blank? next if key.blank? || field_id.blank?
val = info[key] || attributes.multi(key)&.join(",") val = info[key] || attributes.multi(key)&.join(",")
user.custom_fields["user_field_#{field_id}"] = val if val.present? user.custom_fields["user_field_#{field_id}"] = val if val.present?
end end
end end
def sync_moderator(user, attributes) def sync_moderator(user, attributes)
return unless setting(:sync_moderator) return unless setting(:sync_moderator)
is_moderator_attribute = setting(:moderator_attribute) || "isModerator" roles = attributes.multi("roles") || []
is_moderator = %w[1 true].include?(attributes.single(is_moderator_attribute).to_s.downcase) is_moderator = roles.include?("discourse-moderator") or roles.include?("discourse-admin")
return if user.moderator == is_moderator return if user.moderator == is_moderator
...@@ -290,8 +322,8 @@ class SamlAuthenticator < ::Auth::ManagedAuthenticator ...@@ -290,8 +322,8 @@ class SamlAuthenticator < ::Auth::ManagedAuthenticator
def sync_admin(user, attributes) def sync_admin(user, attributes)
return unless setting(:sync_admin) return unless setting(:sync_admin)
is_admin_attribute = setting(:admin_attribute) || "isAdmin" roles = attributes.multi("roles") || []
is_admin = %w[1 true].include?(attributes.single(is_admin_attribute).to_s.downcase) is_admin = roles.include?("discourse-admin")
return if user.admin == is_admin return if user.admin == is_admin
...@@ -369,10 +401,6 @@ class SamlAuthenticator < ::Auth::ManagedAuthenticator ...@@ -369,10 +401,6 @@ class SamlAuthenticator < ::Auth::ManagedAuthenticator
end end
def resolve_username(username, name, email, uid) def resolve_username(username, name, email, uid)
suggester_input = [username, name] username
suggester_input << email if SiteSetting.use_email_for_username_and_name_suggestions
suggester_input << uid
UserNameSuggester.suggest(*suggester_input)
end end
end end