diff --git a/lib/puppet/provider/keycloak_realm/kcadm.rb b/lib/puppet/provider/keycloak_realm/kcadm.rb --- a/lib/puppet/provider/keycloak_realm/kcadm.rb +++ b/lib/puppet/provider/keycloak_realm/kcadm.rb @@ -16,6 +16,23 @@ ] end + def self.smtp_server_properties + [ + :smtp_server_user, + :smtp_server_password, + :smtp_server_host, + :smtp_server_port, + :smtp_server_auth, + :smtp_server_starttls, + :smtp_server_ssl, + :smtp_server_envelope_from, + :smtp_server_from, + :smtp_server_from_display_name, + :smtp_server_reply_to, + :smtp_server_reply_to_display_name, + ] + end + def self.browser_security_headers [ :content_security_policy, @@ -85,6 +102,8 @@ events_config[camelize(property)] elsif browser_security_headers.include?(property) d['browserSecurityHeaders'][camelize(property)] + elsif smtp_server_properties.include?(property) + d['smtpServer'][camelize(property.to_s.gsub(%r{smtp_server_}, ''))] else d[camelize(property)] end @@ -123,11 +142,16 @@ if self.class.browser_security_headers.include?(property) && !data.key?('browserSecurityHeaders') data['browserSecurityHeaders'] = {} end + if self.class.smtp_server_properties.include?(property) && !data.key?('smtpServer') + data['smtpServer'] = {} + end if property.to_s =~ %r{events} events_config[camelize(property)] = convert_property_value(resource[property.to_sym]) elsif resource[property.to_sym] if self.class.browser_security_headers.include?(property) data['browserSecurityHeaders'][camelize(property)] = convert_property_value(resource[property.to_sym]) + elsif self.class.smtp_server_properties.include?(property) && resource[property] + data['smtpServer'][camelize(property.to_s.gsub(%r{smtp_server_}, ''))] = resource[property] else data[camelize(property)] = convert_property_value(resource[property.to_sym]) end @@ -244,9 +268,14 @@ if self.class.browser_security_headers.include?(property) && !data.key?('browserSecurityHeaders') data['browserSecurityHeaders'] = {} end - if @property_flush[property.to_sym] # || resource[property.to_sym] + if self.class.smtp_server_properties.include?(property) && !data.key?('smtpServer') + data['smtpServer'] = {} + end + if @property_flush[property.to_sym] || resource[property.to_sym] if self.class.browser_security_headers.include?(property) data['browserSecurityHeaders'][camelize(property)] = convert_property_value(resource[property.to_sym]) + elsif self.class.smtp_server_properties.include?(property) && resource[property] + data['smtpServer'][camelize(property.to_s.gsub(%r{smtp_server_}, ''))] = resource[property] else data[camelize(property)] = convert_property_value(resource[property.to_sym]) end diff --git a/lib/puppet/type/keycloak_realm.rb b/lib/puppet/type/keycloak_realm.rb --- a/lib/puppet/type/keycloak_realm.rb +++ b/lib/puppet/type/keycloak_realm.rb @@ -186,4 +186,68 @@ newvalues(:true, :false) defaultto :false end + + newproperty(:smtp_server_user) do + desc 'smtpServer user' + end + + newproperty(:smtp_server_password) do + desc 'smtpServer password' + + def insync?(is) + if is =~ %r{^[\*]+$} + Puppet.warning("Property 'smtp_server_password' is set and Puppet has no way to check current value") + true + else + false + end + end + + def should_to_s(_newvalue) + '[new smtp_server_password redacted]' + end + end + + newproperty(:smtp_server_host) do + desc 'smtpServer host' + end + + newproperty(:smtp_server_port, parent: PuppetX::Keycloak::IntegerProperty) do + desc 'smtpServer port' + end + + newproperty(:smtp_server_auth, boolean: true) do + desc 'smtpServer auth' + newvalues(:true, :false) + end + + newproperty(:smtp_server_starttls, boolean: true) do + desc 'smtpServer starttls' + newvalues(:true, :false) + end + + newproperty(:smtp_server_ssl, boolean: true) do + desc 'smtpServer ssl' + newvalues(:true, :false) + end + + newproperty(:smtp_server_from) do + desc 'smtpServer from' + end + + newproperty(:smtp_server_envelope_from) do + desc 'smtpServer envelope_from' + end + + newproperty(:smtp_server_from_display_name) do + desc 'smtpServer fromDisplayName' + end + + newproperty(:smtp_server_reply_to) do + desc 'smtpServer replyto' + end + + newproperty(:smtp_server_reply_to_display_name) do + desc 'smtpServer replyToDisplayName' + end end diff --git a/spec/acceptance/2_realm_spec.rb b/spec/acceptance/2_realm_spec.rb --- a/spec/acceptance/2_realm_spec.rb +++ b/spec/acceptance/2_realm_spec.rb @@ -9,7 +9,18 @@ datasource_driver => 'mysql', } keycloak_realm { 'test': - ensure => 'present', + ensure => 'present', + smtp_server_host => 'smtp.example.org', + smtp_server_port => 587, + smtp_server_starttls => false, + smtp_server_auth => false, + smtp_server_user => 'john', + smtp_server_password => 'secret', + smtp_server_envelope_from => 'keycloak@id.example.org', + smtp_server_from => 'keycloak@id.example.org', + smtp_server_from_display_name => 'Keycloak', + smtp_server_reply_to => 'webmaster@example.org', + smtp_server_reply_to_display_name => 'Webmaster', } EOS @@ -54,6 +65,22 @@ expect(data['adminEventsDetailsEnabled']).to eq(false) end end + + it 'has correct smtp settings' do + on hosts, '/opt/keycloak/bin/kcadm-wrapper.sh get realms/test' do + data = JSON.parse(stdout) + expect(data['smtpServer']['host']).to eq('smtp.example.org') + expect(data['smtpServer']['port']).to eq('587') + expect(data['smtpServer']['starttls']).to eq('false') + expect(data['smtpServer']['auth']).to eq('false') + expect(data['smtpServer']['user']).to eq('john') + expect(data['smtpServer']['envelopeFrom']).to eq('keycloak@id.example.org') + expect(data['smtpServer']['from']).to eq('keycloak@id.example.org') + expect(data['smtpServer']['fromDisplayName']).to eq('Keycloak') + expect(data['smtpServer']['replyTo']).to eq('webmaster@example.org') + expect(data['smtpServer']['replyToDisplayName']).to eq('Webmaster') + end + end end context 'updates realm' do @@ -76,6 +103,18 @@ events_expiration => 2678400, admin_events_enabled => true, admin_events_details_enabled => true, + smtp_server_host => 'smtp.example.org', + smtp_server_port => 587, + smtp_server_starttls => false, + smtp_server_auth => true, + smtp_server_user => 'jane', + smtp_server_password => 'secret', + smtp_server_envelope_from => 'keycloak@id.example.org', + smtp_server_from => 'keycloak@id.example.org', + smtp_server_from_display_name => 'Keycloak', + smtp_server_reply_to => 'webmaster@example.org', + smtp_server_reply_to_display_name => 'Hostmaster', + } EOS @@ -92,6 +131,16 @@ expect(data['ssoSessionIdleTimeout']).to eq(3600) expect(data['ssoSessionMaxLifespan']).to eq(72_000) expect(data['browserSecurityHeaders']['contentSecurityPolicy']).to eq("frame-src https://*.duosecurity.com/ 'self'; frame-src 'self'; frame-ancestors 'self'; object-src 'none';") + expect(data['smtpServer']['host']).to eq('smtp.example.org') + expect(data['smtpServer']['port']).to eq('587') + expect(data['smtpServer']['starttls']).to eq('false') + expect(data['smtpServer']['auth']).to eq('true') + expect(data['smtpServer']['user']).to eq('jane') + expect(data['smtpServer']['envelopeFrom']).to eq('keycloak@id.example.org') + expect(data['smtpServer']['from']).to eq('keycloak@id.example.org') + expect(data['smtpServer']['fromDisplayName']).to eq('Keycloak') + expect(data['smtpServer']['replyTo']).to eq('webmaster@example.org') + expect(data['smtpServer']['replyToDisplayName']).to eq('Hostmaster') end end diff --git a/spec/unit/puppet/type/keycloak_realm_spec.rb b/spec/unit/puppet/type/keycloak_realm_spec.rb --- a/spec/unit/puppet/type/keycloak_realm_spec.rb +++ b/spec/unit/puppet/type/keycloak_realm_spec.rb @@ -68,6 +68,14 @@ :client_authentication_flow, :docker_authentication_flow, :content_security_policy, + :smtp_server_user, + :smtp_server_password, + :smtp_server_host, + :smtp_server_envelope_from, + :smtp_server_from, + :smtp_server_from_display_name, + :smtp_server_reply_to, + :smtp_server_reply_to_display_name, ].each do |p| it "should accept a #{p}" do config[p] = 'foo' @@ -89,6 +97,7 @@ :access_code_lifespan_user_action, :access_token_lifespan, :access_token_lifespan_for_implicit_flow, + :smtp_server_port, ].each do |p| it "should accept a #{p}" do config[p] = 100 @@ -110,6 +119,9 @@ :events_enabled, :admin_events_enabled, :admin_events_details_enabled, + :smtp_server_auth, + :smtp_server_starttls, + :smtp_server_ssl, ].each do |p| it "should accept true for #{p}" do config[p] = true