@@ -27,7 +27,9 @@ class AccountAuthorizationConfig < ActiveRecord::Base
2727 :certificate_fingerprint , :entity_id , :change_password_url ,
2828 :login_handle_name , :ldap_filter , :auth_filter
2929
30+ before_validation :set_saml_entity_id , :if => Proc . new { |aac | aac . saml_authentication? }
3031 validates_presence_of :account_id
32+ validates_presence_of :entity_id , :if => Proc . new { |aac | aac . saml_authentication? }
3133 after_save :disable_open_registration_if_delegated
3234
3335 def ldap_connection
@@ -41,6 +43,10 @@ def ldap_connection
4143 ldap
4244 end
4345
46+ def set_saml_entity_id
47+ self . entity_id ||= saml_default_entity_id
48+ end
49+
4450 def sanitized_ldap_login ( login )
4551 [ [ '\\' , '\5c' ] , [ '*' , '\2a' ] , [ '(' , '\28' ] , [ ')' , '\29' ] , [ "\00 " , '\00' ] ] . each do |re |
4652 login . gsub! ( re [ 0 ] , re [ 1 ] )
@@ -79,56 +85,75 @@ def auth_decrypted_password
7985 return nil unless self . auth_password_salt && self . auth_crypted_password
8086 Canvas ::Security . decrypt_password ( self . auth_crypted_password , self . auth_password_salt , 'instructure_auth' )
8187 end
88+
89+ def self . saml_default_entity_id_for_account ( account )
90+ "http://#{ HostUrl . context_host ( account ) } /saml2"
91+ end
92+
93+ def saml_default_entity_id
94+ AccountAuthorizationConfig . saml_default_entity_id_for_account ( self . account )
95+ end
8296
8397 def saml_settings ( preferred_account_domain = nil )
8498 return nil unless self . auth_type == 'saml'
85- app_config = Setting . from_config ( 'saml' )
86- raise "This Canvas instance isn't configured for SAML" unless app_config
8799
88100 unless @saml_settings
89- domain = HostUrl . context_host ( self . account , preferred_account_domain )
90- @saml_settings = Onelogin ::Saml ::Settings . new
101+ @saml_settings = AccountAuthorizationConfig . saml_settings_for_account ( self . account , preferred_account_domain )
91102
92- @saml_settings . issuer = self . entity_id || app_config [ :entity_id ]
93103 @saml_settings . idp_sso_target_url = self . log_in_url
94104 @saml_settings . idp_slo_target_url = self . log_out_url
95105 @saml_settings . idp_cert_fingerprint = self . certificate_fingerprint
96106 @saml_settings . name_identifier_format = self . identifier_format
97- if ENV [ 'RAILS_ENV' ] == 'development'
98- # if you set the domain to go to your local box in /etc/hosts you can test saml
99- @saml_settings . assertion_consumer_service_url = "http://#{ domain } /saml_consume"
100- @saml_settings . sp_slo_url = "http://#{ domain } /saml_logout"
101- else
102- @saml_settings . assertion_consumer_service_url = "https://#{ domain } /saml_consume"
103- @saml_settings . sp_slo_url = "https://#{ domain } /saml_logout"
104- end
105- @saml_settings . tech_contact_name = app_config [ :tech_contact_name ] || 'Webmaster'
106- @saml_settings . tech_contact_email = app_config [ :tech_contact_email ]
107-
108- encryption = app_config [ :encryption ]
109- if encryption . is_a? ( Hash ) && File . exists? ( encryption [ :xmlsec_binary ] )
110- resolve_path = lambda { |path |
111- if path . nil?
112- nil
113- elsif path [ 0 , 1 ] == '/'
114- path
115- else
116- File . join ( Rails . root , 'config' , path )
117- end
118- }
119-
120- private_key_path = resolve_path . call ( encryption [ :private_key ] )
121- certificate_path = resolve_path . call ( encryption [ :certificate ] )
122-
123- if File . exists? ( private_key_path ) && File . exists? ( certificate_path )
124- @saml_settings . xmlsec1_path = encryption [ :xmlsec_binary ]
125- @saml_settings . xmlsec_certificate = certificate_path
126- @saml_settings . xmlsec_privatekey = private_key_path
107+ end
108+
109+ @saml_settings
110+ end
111+
112+ def self . saml_settings_for_account ( account , preferred_account_domain = nil )
113+ app_config = Setting . from_config ( 'saml' ) || { }
114+ domain = HostUrl . context_host ( account , preferred_account_domain )
115+
116+ settings = Onelogin ::Saml ::Settings . new
117+ if ENV [ 'RAILS_ENV' ] == 'development'
118+ # if you set the domain to go to your local box in /etc/hosts you can test saml
119+ settings . assertion_consumer_service_url = "http://#{ domain } /saml_consume"
120+ settings . sp_slo_url = "http://#{ domain } /saml_logout"
121+ else
122+ settings . assertion_consumer_service_url = "https://#{ domain } /saml_consume"
123+ settings . sp_slo_url = "https://#{ domain } /saml_logout"
124+ end
125+ settings . tech_contact_name = app_config [ :tech_contact_name ] || 'Webmaster'
126+ settings . tech_contact_email = app_config [ :tech_contact_email ] || ''
127+
128+ if account . saml_authentication?
129+ settings . issuer = account . account_authorization_config . entity_id
130+ else
131+ settings . issuer = saml_default_entity_id_for_account ( account )
132+ end
133+
134+ encryption = app_config [ :encryption ]
135+ if encryption . is_a? ( Hash ) && File . exists? ( encryption [ :xmlsec_binary ] )
136+ resolve_path = lambda { |path |
137+ if path . nil?
138+ nil
139+ elsif path [ 0 , 1 ] == '/'
140+ path
141+ else
142+ File . join ( Rails . root , 'config' , path )
127143 end
144+ }
145+
146+ private_key_path = resolve_path . call ( encryption [ :private_key ] )
147+ certificate_path = resolve_path . call ( encryption [ :certificate ] )
148+
149+ if File . exists? ( private_key_path ) && File . exists? ( certificate_path )
150+ settings . xmlsec1_path = encryption [ :xmlsec_binary ]
151+ settings . xmlsec_certificate = certificate_path
152+ settings . xmlsec_privatekey = private_key_path
128153 end
129154 end
130155
131- @saml_settings
156+ settings
132157 end
133158
134159 def email_identifier?
0 commit comments