diff --git a/lib/puppet/type/keycloak_identity_provider.rb b/lib/puppet/type/keycloak_identity_provider.rb index 50b0d65..145c63f 100644 --- a/lib/puppet/type/keycloak_identity_provider.rb +++ b/lib/puppet/type/keycloak_identity_provider.rb @@ -1,294 +1,309 @@ require_relative '../../puppet_x/keycloak/type' require_relative '../../puppet_x/keycloak/array_property' require_relative '../../puppet_x/keycloak/integer_property' Puppet::Type.newtype(:keycloak_identity_provider) do desc <<-DESC Manage Keycloak identity providers @example Add CILogon identity provider to test realm keycloak_identity_provider { 'cilogon on test': ensure => 'present', display_name => 'CILogon', provider_id => 'oidc', first_broker_login_flow_alias => 'browser', client_id => 'cilogon:/client_id/foobar', client_secret => 'supersecret', user_info_url => 'https://cilogon.org/oauth2/userinfo', token_url => 'https://cilogon.org/oauth2/token', authorization_url => 'https://cilogon.org/authorize', } DESC extend PuppetX::Keycloak::Type add_autorequires ensurable newparam(:name, namevar: true) do desc 'The identity provider name' end newparam(:alias, namevar: true) do desc 'The identity provider name. Defaults to `name`.' defaultto do @resource[:name] end end newparam(:internal_id) do desc 'internalId. Defaults to "`alias`-`realm`"' defaultto do "#{@resource[:alias]}-#{@resource[:realm]}" end end newparam(:realm, namevar: true) do desc 'realm' end newproperty(:display_name) do desc 'displayName' end newparam(:provider_id) do desc 'providerId' newvalues('oidc', 'keycloak-oidc') defaultto 'oidc' munge { |v| v } end newproperty(:enabled, boolean: true) do desc 'enabled' newvalues(:true, :false) defaultto :true end newproperty(:update_profile_first_login_mode) do desc 'updateProfileFirstLoginMode' defaultto 'on' newvalues('on', 'off') munge { |v| v } end newproperty(:trust_email, boolean: true) do desc 'trustEmail' newvalues(:true, :false) defaultto :false end newproperty(:store_token, boolean: true) do desc 'storeToken' newvalues(:true, :false) defaultto :false end newproperty(:add_read_token_role_on_create, boolean: true) do desc 'addReadTokenRoleOnCreate' newvalues(:true, :false) defaultto :false end newproperty(:authenticate_by_default, boolean: true) do desc 'authenticateByDefault' newvalues(:true, :false) defaultto :false end newproperty(:link_only, boolean: true) do desc 'linkOnly' newvalues(:true, :false) defaultto :false end newproperty(:gui_order, parent: PuppetX::Keycloak::IntegerProperty) do desc 'guiOrder' munge { |v| v.to_s } end newproperty(:first_broker_login_flow_alias) do desc 'firstBrokerLoginFlowAlias' defaultto 'first broker login' munge { |v| v } end newproperty(:post_broker_login_flow_alias) do desc 'postBrokerLoginFlowAlias' munge { |v| v } end newproperty(:sync_mode) do desc 'syncMode' defaultto 'IMPORT' newvalues('IMPORT', 'LEGACY', 'FORCE') munge { |v| v } end # BEGIN: oidc newproperty(:hide_on_login_page, boolean: true) do desc 'hideOnLoginPage' newvalues(:true, :false) defaultto :false end newproperty(:user_info_url) do desc 'userInfoUrl' munge { |v| v } end newproperty(:validate_signature, boolean: true) do desc 'validateSignature' newvalues(:true, :false) defaultto :false end newproperty(:client_id) do desc 'clientId' end newproperty(:client_secret) do desc 'clientSecret' def insync?(is) if is =~ %r{^[\*]+$} Puppet.warning("Parameter 'client_secret' is set and Puppet has no way to check current value") true else false end end def change_to_s(currentvalue, _newvalue) if currentvalue == :absent 'created client_secret' else 'changed client_secret' end end def is_to_s(_currentvalue) # rubocop:disable Style/PredicateName '[old client_secret redacted]' end def should_to_s(_newvalue) '[new client_secret redacted]' end end newproperty(:client_auth_method) do desc 'clientAuthMethod' newvalues('client_secret_post', 'client_secret_basic', 'client_secret_jwt', 'private_key_jwt') defaultto('client_secret_post') munge { |v| v.to_s } end newproperty(:token_url) do desc 'tokenUrl' end newproperty(:ui_locales, boolean: true) do desc 'uiLocales' newvalues(:true, :false) defaultto :false end newproperty(:backchannel_supported, boolean: true) do desc 'backchannelSupported' newvalues(:true, :false) defaultto :false end newproperty(:use_jwks_url, boolean: true) do desc 'useJwksUrl' newvalues(:true, :false) defaultto :true end newproperty(:jwks_url) do desc 'jwksUrl' munge { |v| v } end newproperty(:login_hint, boolean: true) do desc 'loginHint' newvalues(:true, :false) defaultto :false end newproperty(:authorization_url) do desc 'authorizationUrl' end newproperty(:disable_user_info, boolean: true) do desc 'disableUserInfo' newvalues(:true, :false) defaultto :false end newproperty(:logout_url) do desc 'logoutUrl' end newproperty(:issuer) do desc 'issuer' end newproperty(:default_scope) do desc 'default_scope' end newproperty(:prompt) do desc 'prompt' newvalues('none', 'consent', 'login', 'select_account') munge { |v| v } end newproperty(:allowed_clock_skew) do desc 'allowedClockSkew' end newproperty(:forward_parameters) do desc 'forwardParameters' end # END: oidc def self.title_patterns [ [ %r{^((\S+) on (\S+))$}, [ [:name], [:alias], [:realm], ], ], [ %r{(.*)}, [ [:name], ], ], ] end validate do if self[:realm].nil? raise Puppet::Error, 'realm is required' end if self[:ensure].to_s == 'present' && ['oidc', 'keycloak-oidc'].include?(self[:provider_id]) if self[:authorization_url].nil? raise Puppet::Error, 'authorization_url is required' end if self[:token_url].nil? raise Puppet::Error, 'token_url is required' end if self[:client_id].nil? raise Puppet::Error, 'client_id is required' end if self[:client_secret].nil? raise Puppet::Error, 'client_secret is required' end end end + + autorequire(:keycloak_flow) do + requires = [] + catalog.resources.each do |resource| + next unless resource.class.to_s == 'Puppet::Type::Keycloak_flow' + next if self[:realm] != resource[:realm] + if self[:first_broker_login_flow_alias] == resource[:alias] + requires << resource.name + end + if self[:post_broker_login_flow_alias] == resource[:alias] + requires << resource.name + end + end + requires + end end diff --git a/lib/puppet/type/keycloak_realm.rb b/lib/puppet/type/keycloak_realm.rb index 3393ec8..1a2896f 100644 --- a/lib/puppet/type/keycloak_realm.rb +++ b/lib/puppet/type/keycloak_realm.rb @@ -1,264 +1,291 @@ require_relative '../../puppet_x/keycloak/type' require_relative '../../puppet_x/keycloak/array_property' require_relative '../../puppet_x/keycloak/integer_property' Puppet::Type.newtype(:keycloak_realm) do desc <<-DESC Manage Keycloak realms @example Add a realm with a custom theme keycloak_realm { 'test': ensure => 'present', remember_me => true, login_with_email_allowed => false, login_theme => 'my_theme', } DESC extend PuppetX::Keycloak::Type add_autorequires(false) ensurable newparam(:name, namevar: true) do desc 'The realm name' end newparam(:id) do desc 'Id. Default to `name`.' defaultto do @resource[:name] end end newproperty(:display_name) do desc 'displayName' end newproperty(:display_name_html) do desc 'displayNameHtml' end newproperty(:login_theme) do desc 'loginTheme' defaultto 'keycloak' end newproperty(:account_theme) do desc 'accountTheme' defaultto 'keycloak' end newproperty(:admin_theme) do desc 'adminTheme' defaultto 'keycloak' end newproperty(:email_theme) do desc 'emailTheme' defaultto 'keycloak' end newproperty(:internationalization_enabled, boolean: true) do desc 'internationalizationEnabled' newvalues(:true, :false) defaultto :false end newproperty(:sso_session_idle_timeout, parent: PuppetX::Keycloak::IntegerProperty) do desc 'ssoSessionIdleTimeout' end newproperty(:sso_session_max_lifespan, parent: PuppetX::Keycloak::IntegerProperty) do desc 'ssoSessionMaxLifespan' end newproperty(:access_code_lifespan, parent: PuppetX::Keycloak::IntegerProperty) do desc 'accessCodeLifespan' end newproperty(:access_code_lifespan_user_action, parent: PuppetX::Keycloak::IntegerProperty) do desc 'accessCodeLifespanUserAction' end newproperty(:access_token_lifespan, parent: PuppetX::Keycloak::IntegerProperty) do desc 'accessTokenLifespan' end newproperty(:access_token_lifespan_for_implicit_flow, parent: PuppetX::Keycloak::IntegerProperty) do desc 'accessTokenLifespanForImplicitFlow' end newproperty(:enabled, boolean: true) do desc 'enabled' newvalues(:true, :false) defaultto :true end newproperty(:remember_me, boolean: true) do desc 'rememberMe' newvalues(:true, :false) defaultto :false end newproperty(:registration_allowed, boolean: true) do desc 'registrationAllowed' newvalues(:true, :false) defaultto :false end newproperty(:login_with_email_allowed, boolean: true) do desc 'loginWithEmailAllowed' newvalues(:true, :false) defaultto :true end newproperty(:browser_flow) do desc 'browserFlow' defaultto('browser') munge { |v| v.to_s } end newproperty(:registration_flow) do desc 'registrationFlow' defaultto('registration') munge { |v| v.to_s } end newproperty(:direct_grant_flow) do desc 'directGrantFlow' defaultto('direct grant') munge { |v| v.to_s } end newproperty(:reset_credentials_flow) do desc 'resetCredentialsFlow' defaultto('reset credentials') munge { |v| v.to_s } end newproperty(:client_authentication_flow) do desc 'clientAuthenticationFlow' defaultto('clients') munge { |v| v.to_s } end newproperty(:docker_authentication_flow) do desc 'dockerAuthenticationFlow' defaultto('docker auth') munge { |v| v.to_s } end newproperty(:default_client_scopes, array_matching: :all, parent: PuppetX::Keycloak::ArrayProperty) do desc 'Default Client Scopes' end newproperty(:optional_client_scopes, array_matching: :all, parent: PuppetX::Keycloak::ArrayProperty) do desc 'Optional Client Scopes' end newproperty(:supported_locales, array_matching: :all, parent: PuppetX::Keycloak::ArrayProperty) do desc 'Supported Locales' end newproperty(:content_security_policy) do desc 'contentSecurityPolicy' defaultto("frame-src 'self'; frame-ancestors 'self'; object-src 'none';") munge { |v| v.to_s } end newproperty(:events_enabled, boolean: true) do desc 'eventsEnabled' newvalues(:true, :false) defaultto :false end newproperty(:events_expiration) do desc 'eventsExpiration' end newproperty(:events_listeners, array_matching: :all, parent: PuppetX::Keycloak::ArrayProperty) do desc 'eventsListeners' defaultto ['jboss-logging'] end newproperty(:admin_events_enabled, boolean: true) do desc 'adminEventsEnabled' newvalues(:true, :false) defaultto :false end newproperty(:admin_events_details_enabled, boolean: true) do desc 'adminEventsDetailsEnabled' 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 newproperty(:brute_force_protected, boolean: true) do desc 'bruteForceProtected' newvalues(:true, :false) end + + autorequire(:keycloak_flow) do + requires = [] + catalog.resources.each do |resource| + next unless resource.class.to_s == 'Puppet::Type::Keycloak_flow' + next if self[:name] != resource[:realm] + if self[:browser_flow] == resource[:alias] + requires << resource.name + end + if self[:registration_flow] == resource[:alias] + requires << resource.name + end + if self[:direct_grant_flow] == resource[:alias] + requires << resource.name + end + if self[:reset_credentials_flow] == resource[:alias] + requires << resource.name + end + if self[:client_authentication_flow] == resource[:alias] + requires << resource.name + end + if self[:docker_authentication_flow] == resource[:alias] + requires << resource.name + end + end + requires + end end diff --git a/spec/unit/puppet/type/keycloak_identity_provider_spec.rb b/spec/unit/puppet/type/keycloak_identity_provider_spec.rb index 6066991..9f27b82 100644 --- a/spec/unit/puppet/type/keycloak_identity_provider_spec.rb +++ b/spec/unit/puppet/type/keycloak_identity_provider_spec.rb @@ -1,303 +1,314 @@ require 'spec_helper' describe Puppet::Type.type(:keycloak_identity_provider) do let(:default_config) do { name: 'foo', realm: 'test', authorization_url: 'http://authorization', token_url: 'http://token', client_id: 'foobar', client_secret: 'secret', } end let(:config) do default_config end let(:resource) do described_class.new(config) end it 'adds to catalog without raising an error' do catalog = Puppet::Resource::Catalog.new expect { catalog.add_resource resource }.not_to raise_error end it 'has a name' do expect(resource[:name]).to eq('foo') end it 'has alias default to name' do expect(resource[:alias]).to eq('foo') end it 'has internal_id default to resource_name-realm' do expect(resource[:internal_id]).to eq('foo-test') end it 'has realm' do expect(resource[:realm]).to eq('test') end it 'handles componsite name' do component = described_class.new(name: 'foo on test') expect(component[:name]).to eq('foo on test') expect(component[:alias]).to eq('foo') expect(component[:realm]).to eq('test') end it 'defaults to provider_id=oidc' do expect(resource[:provider_id]).to eq('oidc') end it 'allows keycloak-oidc' do config[:provider_id] = 'keycloak-oidc' expect(resource[:provider_id]).to eq('keycloak-oidc') end it 'does not allow invalid provider_id' do config[:provider_id] = 'foo' expect { resource }.to raise_error(%r{foo}) end it 'defaults to update_profile_first_login_mode=on' do expect(resource[:update_profile_first_login_mode]).to eq('on') end it 'does not allow invalid update_profile_first_login_mode' do config[:update_profile_first_login_mode] = 'foo' expect { resource }.to raise_error(%r{foo}) end it 'defaults to prompt undefined' do expect(resource[:prompt]).to be_nil end it 'does not allow invalid prompt' do config[:prompt] = 'foo' expect { resource }.to raise_error(%r{foo}) end defaults = { enabled: :true, trust_email: :false, store_token: :false, add_read_token_role_on_create: :false, authenticate_by_default: :false, link_only: :false, first_broker_login_flow_alias: 'first broker login', hide_on_login_page: :false, validate_signature: :false, ui_locales: :false, backchannel_supported: :false, use_jwks_url: :true, login_hint: :false, disable_user_info: :false, } describe 'basic properties' do # Test basic properties [ :display_name, :first_broker_login_flow_alias, :post_broker_login_flow_alias, :user_info_url, :client_id, :token_url, :authorization_url, :logout_url, :issuer, :default_scope, :allowed_clock_skew, :forward_parameters, :jwks_url, ].each do |p| it "should accept a #{p}" do config[p] = 'foo' expect(resource[p]).to eq('foo') end next unless defaults[p] it "should have default for #{p}" do expect(resource[p]).to eq(defaults[p]) end end end describe 'integer properties' do # Test integer properties [ :gui_order, ].each do |p| it "should accept a #{p}" do config[p] = 100 expect(resource[p]).to eq('100') end next unless defaults[p] it "should have default for #{p}" do expect(resource[p]).to eq(defaults[p]) end end end describe 'boolean properties' do # Test boolean properties [ :enabled, :trust_email, :store_token, :add_read_token_role_on_create, :authenticate_by_default, :link_only, :hide_on_login_page, :validate_signature, :ui_locales, :backchannel_supported, :use_jwks_url, :login_hint, :disable_user_info, ].each do |p| it "should accept true for #{p}" do config[p] = true expect(resource[p]).to eq(:true) config[p] = 'true' expect(resource[p]).to eq(:true) end it "should accept false for #{p}" do config[p] = false expect(resource[p]).to eq(:false) config[p] = 'false' expect(resource[p]).to eq(:false) end it "should not accept strings for #{p}" do config[p] = 'foo' expect { resource }.to raise_error(%r{foo}) end next unless defaults[p] it "should have default for #{p}" do expect(resource[p]).to eq(defaults[p]) end end end describe 'array properties' do # Array properties [ ].each do |p| it 'accepts array' do config[p] = ['foo', 'bar'] expect(resource[p]).to eq(['foo', 'bar']) end next unless defaults[p] it "should have default for #{p}" do expect(resource[p]).to eq(defaults[p]) end end end describe 'client_auth_method' do [ 'client_secret_post', 'client_secret_basic', 'client_secret_jwt', 'private_key_jwt' ].each do |v| it "accepts #{v}" do config[:client_auth_method] = v expect(resource[:client_auth_method]).to eq(v) end end it 'does not accept invalid values' do config[:client_auth_method] = 'foo' expect { resource }.to raise_error(%r{Invalid}) end end describe 'sync_mode' do [ 'IMPORT', 'LEGACY', 'FORCE' ].each do |v| it "accepts #{v}" do config[:sync_mode] = v expect(resource[:sync_mode]).to eq(v) end end it 'does not accept invalid values' do config[:sync_mode] = 'foo' expect { resource }.to raise_error(%r{Invalid}) end end it 'autorequires keycloak_conn_validator' do keycloak_conn_validator = Puppet::Type.type(:keycloak_conn_validator).new(name: 'keycloak') catalog = Puppet::Resource::Catalog.new catalog.add_resource resource catalog.add_resource keycloak_conn_validator rel = resource.autorequire[0] expect(rel.source.ref).to eq(keycloak_conn_validator.ref) expect(rel.target.ref).to eq(resource.ref) end it 'autorequires kcadm-wrapper.sh' do file = Puppet::Type.type(:file).new(name: 'kcadm-wrapper.sh', path: '/opt/keycloak/bin/kcadm-wrapper.sh') catalog = Puppet::Resource::Catalog.new catalog.add_resource resource catalog.add_resource file rel = resource.autorequire[0] expect(rel.source.ref).to eq(file.ref) expect(rel.target.ref).to eq(resource.ref) end it 'autorequires keycloak_realm' do keycloak_realm = Puppet::Type.type(:keycloak_realm).new(name: 'test') catalog = Puppet::Resource::Catalog.new catalog.add_resource resource catalog.add_resource keycloak_realm rel = resource.autorequire[0] expect(rel.source.ref).to eq(keycloak_realm.ref) expect(rel.target.ref).to eq(resource.ref) end + it 'autorequires browser flow' do + config[:first_broker_login_flow_alias] = 'foo' + flow = Puppet::Type.type(:keycloak_flow).new(name: 'foo', realm: 'test') + catalog = Puppet::Resource::Catalog.new + catalog.add_resource resource + catalog.add_resource flow + rel = resource.autorequire[0] + expect(rel.source.ref).to eq(flow.ref) + expect(rel.target.ref).to eq(resource.ref) + end + it 'requires realm' do config[:ensure] = :present config[:provider_id] = 'oidc' config.delete(:realm) expect { resource }.to raise_error(Puppet::Error, %r{realm is required}) end it 'requires authorization_url' do config[:ensure] = :present config[:provider_id] = 'oidc' config.delete(:authorization_url) expect { resource }.to raise_error(Puppet::Error, %r{authorization_url is required}) end it 'requires token_url' do config[:ensure] = :present config[:provider_id] = 'oidc' config.delete(:token_url) expect { resource }.to raise_error(Puppet::Error, %r{token_url is required}) end it 'requires client_id' do config[:ensure] = :present config[:provider_id] = 'oidc' config.delete(:client_id) expect { resource }.to raise_error(Puppet::Error, %r{client_id is required}) end it 'requires client_secret' do config[:ensure] = :present config[:provider_id] = 'oidc' config.delete(:client_secret) expect { resource }.to raise_error(Puppet::Error, %r{client_secret is required}) end end diff --git a/spec/unit/puppet/type/keycloak_realm_spec.rb b/spec/unit/puppet/type/keycloak_realm_spec.rb index 1495724..22deb97 100644 --- a/spec/unit/puppet/type/keycloak_realm_spec.rb +++ b/spec/unit/puppet/type/keycloak_realm_spec.rb @@ -1,195 +1,206 @@ require 'spec_helper' describe Puppet::Type.type(:keycloak_realm) do let(:default_config) do { name: 'test', } end let(:config) do default_config end let(:resource) do described_class.new(config) end it 'adds to catalog without raising an error' do catalog = Puppet::Resource::Catalog.new expect { catalog.add_resource resource }.not_to raise_error end it 'has a name' do expect(resource[:name]).to eq('test') end it 'has id default to name' do expect(resource[:id]).to eq('test') end defaults = { login_theme: 'keycloak', account_theme: 'keycloak', admin_theme: 'keycloak', email_theme: 'keycloak', access_code_lifespan_user_action: nil, access_token_lifespan_for_implicit_flow: nil, enabled: :true, remember_me: :false, login_with_email_allowed: :true, browser_flow: 'browser', registration_flow: 'registration', direct_grant_flow: 'direct grant', reset_credentials_flow: 'reset credentials', client_authentication_flow: 'clients', docker_authentication_flow: 'docker auth', content_security_policy: "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", events_enabled: :false, events_listeners: ['jboss-logging'], admin_events_enabled: :false, admin_events_details_enabled: :false, } describe 'basic properties' do # Test basic properties [ :display_name, :display_name_html, :login_theme, :account_theme, :admin_theme, :email_theme, :events_expiration, :browser_flow, :registration_flow, :direct_grant_flow, :reset_credentials_flow, :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' expect(resource[p]).to eq('foo') end next unless defaults[p] it "should have default for #{p}" do expect(resource[p]).to eq(defaults[p]) end end end describe 'integer properties' do # Test integer properties [ :sso_session_idle_timeout, :sso_session_max_lifespan, :access_code_lifespan, :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 expect(resource[p]).to eq(100) end next unless defaults[p] it "should have default for #{p}" do expect(resource[p]).to eq(defaults[p]) end end end describe 'boolean properties' do # Test boolean properties [ :remember_me, :registration_allowed, :login_with_email_allowed, :internationalization_enabled, :events_enabled, :admin_events_enabled, :admin_events_details_enabled, :smtp_server_auth, :smtp_server_starttls, :smtp_server_ssl, :brute_force_protected, ].each do |p| it "should accept true for #{p}" do config[p] = true expect(resource[p]).to eq(:true) end it "should accept true for #{p} string" do config[p] = 'true' expect(resource[p]).to eq(:true) end it "should accept false for #{p}" do config[p] = false expect(resource[p]).to eq(:false) end it "should accept false for #{p} string" do config[p] = 'false' expect(resource[p]).to eq(:false) end it "should not accept strings for #{p}" do config[p] = 'foo' expect { resource }.to raise_error(%r{foo}) end next unless defaults[p] it "should have default for #{p}" do expect(resource[p]).to eq(defaults[p]) end end end describe 'array properties' do # Array properties [ :default_client_scopes, :optional_client_scopes, :events_listeners, :supported_locales, ].each do |p| it "should accept array for #{p}" do config[p] = ['foo', 'bar'] expect(resource[p]).to eq(['foo', 'bar']) end next unless defaults[p] it "should have default for #{p}" do expect(resource[p]).to eq(defaults[p]) end end end it 'autorequires keycloak_conn_validator' do keycloak_conn_validator = Puppet::Type.type(:keycloak_conn_validator).new(name: 'keycloak') catalog = Puppet::Resource::Catalog.new catalog.add_resource resource catalog.add_resource keycloak_conn_validator rel = resource.autorequire[0] expect(rel.source.ref).to eq(keycloak_conn_validator.ref) expect(rel.target.ref).to eq(resource.ref) end it 'autorequires kcadm-wrapper.sh' do file = Puppet::Type.type(:file).new(name: 'kcadm-wrapper.sh', path: '/opt/keycloak/bin/kcadm-wrapper.sh') catalog = Puppet::Resource::Catalog.new catalog.add_resource resource catalog.add_resource file rel = resource.autorequire[0] expect(rel.source.ref).to eq(file.ref) expect(rel.target.ref).to eq(resource.ref) end + + it 'autorequires browser flow' do + config[:browser_flow] = 'foo' + flow = Puppet::Type.type(:keycloak_flow).new(name: 'foo', realm: 'test') + catalog = Puppet::Resource::Catalog.new + catalog.add_resource resource + catalog.add_resource flow + rel = resource.autorequire[0] + expect(rel.source.ref).to eq(flow.ref) + expect(rel.target.ref).to eq(resource.ref) + end end