Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement realm otp, webauthn, webauthn passwordless and bruteforce properties #312

186 changes: 186 additions & 0 deletions lib/puppet/type/keycloak_realm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -338,12 +338,88 @@ def should_to_s(_newvalue)
newvalues(:true, :false)
end

newproperty(:permanent_lockout, boolean: true) do
desc 'permanentLockout'
newvalues(:true, :false)
defaultto :false
end

newproperty(:max_failure_wait_seconds, parent: PuppetX::Keycloak::IntegerProperty) do
desc 'maxFailureWaitSeconds'
defaultto 900
end

newproperty(:minimum_quick_login_wait_seconds, parent: PuppetX::Keycloak::IntegerProperty) do
desc 'minimumQuickLoginWaitSeconds'
defaultto 60
end

newproperty(:wait_increment_seconds, parent: PuppetX::Keycloak::IntegerProperty) do
desc 'waitIncrementSeconds'
defaultto 60
end

newproperty(:quick_login_check_milli_seconds, parent: PuppetX::Keycloak::IntegerProperty) do
desc 'quickLoginCheckMilliSeconds'
defaultto 1_000
end

newproperty(:max_delta_time_seconds, parent: PuppetX::Keycloak::IntegerProperty) do
desc 'maxDeltaTimeSeconds'
defaultto 43_200
end

newproperty(:failure_factor, parent: PuppetX::Keycloak::IntegerProperty) do
desc 'failureFactor'
defaultto 30
end

newparam(:manage_roles, boolean: true) do
desc 'Manage realm roles'
newvalues(:true, :false)
defaultto(:true)
end

newproperty(:otp_policy_type) do
desc 'otpPolicyType'
newvalues('totp', 'hotp')
defaultto 'totp'
end

newproperty(:otp_policy_algorithm) do
desc 'otpPolicyAlgorithm'
newvalues('HmacSHA1', 'HmacSHA256', 'HmacSHA512')
defaultto 'HmacSHA1'
end

newproperty(:otp_policy_initial_counter, parent: PuppetX::Keycloak::IntegerProperty) do
desc 'otpPolicyInitialCounter'
defaultto 0
end

newproperty(:otp_policy_digits) do
desc 'otpPolicyDigits'
newvalues(6, 8)
defaultto 6
munge { |v| v.to_i }
end

newproperty(:otp_policy_look_ahead_window, parent: PuppetX::Keycloak::IntegerProperty) do
desc 'otpPolicyLookAheadWindow'
defaultto 1
end

newproperty(:otp_policy_period, parent: PuppetX::Keycloak::IntegerProperty) do
desc 'otpPolicyPeriod'
defaultto 30
end

newproperty(:otp_policy_code_reusable, boolean: true) do
desc 'otpPolicyCodeReusable'
newvalues(:true, :false)
defaultto :false
end

newproperty(:roles, array_matching: :all, parent: PuppetX::Keycloak::ArrayProperty) do
desc 'roles'
defaultto ['offline_access', 'uma_authorization']
Expand All @@ -357,6 +433,116 @@ def insync?(is)
end
end

newproperty(:web_authn_policy_rp_entity_name) do
desc 'webAuthnPolicyRpEntityName'
defaultto 'keycloak'
end

newproperty(:web_authn_policy_signature_algorithms, array_matching: :all, parent: PuppetX::Keycloak::ArrayProperty) do
desc 'webAuthnPolicySignatureAlgorithms'
defaultto ['ES256']
end

newproperty(:web_authn_policy_rp_id) do
desc 'webAuthnPolicyRpId'
defaultto ''
end

newproperty(:web_authn_policy_attestation_conveyance_preference) do
desc 'webAuthnPolicyAttestationConveyancePreference'
newvalues('none', 'direct', 'indirect', 'not specified')
defaultto 'not specified'
end

newproperty(:web_authn_policy_authenticator_attachment) do
desc 'webAuthnPolicyAuthenticatorAttachment'
newvalues('platform', 'cross-platform', 'not specified')
defaultto 'not specified'
end

newproperty(:web_authn_policy_require_resident_key) do
desc 'webAuthnPolicyRequireResidentKey'
newvalues('No', 'Yes', 'not specified')
defaultto 'not specified'
end

newproperty(:web_authn_policy_user_verification_requirement) do
desc 'webAuthnPolicyUserVerificationRequirement'
newvalues('required', 'preferred', 'discouraged', 'not specified')
defaultto 'not specified'
end

newproperty(:web_authn_policy_create_timeout, parent: PuppetX::Keycloak::IntegerProperty) do
desc 'webAuthnPolicyCreateTimeout'
defaultto 0
end

newproperty(:web_authn_policy_avoid_same_authenticator_register, boolean: true) do
desc 'webAuthnPolicyAvoidSameAuthenticatorRegister'
newvalues(:true, :false)
defaultto :false
end

newproperty(:web_authn_policy_acceptable_aaguids, array_matching: :all, parent: PuppetX::Keycloak::ArrayProperty) do
desc 'webAuthnPolicyAcceptableAaguids'
defaultto []
end

newproperty(:web_authn_policy_passwordless_rp_entity_name) do
desc 'webAuthnPolicyPasswordlessRpEntityName'
defaultto 'keycloak'
end

newproperty(:web_authn_policy_passwordless_signature_algorithms, array_matching: :all, parent: PuppetX::Keycloak::ArrayProperty) do
desc 'webAuthnPolicyPasswordlessSignatureAlgorithms'
defaultto ['ES256']
end

newproperty(:web_authn_policy_passwordless_rp_id) do
desc 'webAuthnPolicyPasswordlessRpId'
defaultto ''
end

newproperty(:web_authn_policy_passwordless_attestation_conveyance_preference) do
desc 'webAuthnPolicyPasswordlessAttestationConveyancePreference'
newvalues('none', 'direct', 'indirect', 'not specified')
defaultto 'not specified'
end

newproperty(:web_authn_policy_passwordless_authenticator_attachment) do
desc 'webAuthnPolicyPasswordlessAuthenticatorAttachment'
newvalues('platform', 'cross-platform', 'not specified')
defaultto 'not specified'
end

newproperty(:web_authn_policy_passwordless_require_resident_key) do
desc 'webAuthnPolicyPasswordlessRequireResidentKey'
newvalues('No', 'Yes', 'not specified')
defaultto 'not specified'
end

newproperty(:web_authn_policy_passwordless_user_verification_requirement) do
desc 'webAuthnPolicyPasswordlessUserVerificationRequirement'
newvalues('required', 'preferred', 'discouraged', 'not specified')
defaultto 'not specified'
end

newproperty(:web_authn_policy_passwordless_create_timeout, parent: PuppetX::Keycloak::IntegerProperty) do
desc 'webAuthnPolicyPasswordlessCreateTimeout'
defaultto 0
end

newproperty(:web_authn_policy_passwordless_avoid_same_authenticator_register, boolean: true) do
desc 'webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister'
newvalues(:true, :false)
defaultto :false
end

newproperty(:web_authn_policy_passwordless_acceptable_aaguids, array_matching: :all, parent: PuppetX::Keycloak::ArrayProperty) do
desc 'webAuthnPolicyPasswordlessAcceptableAaguids'
defaultto []
end

newproperty(:custom_properties) do
desc 'custom properties to pass as realm configurations'
defaultto {}
Expand Down
66 changes: 65 additions & 1 deletion spec/acceptance/2_realm_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,41 @@ class { 'keycloak': }
default_locale => 'en',
supported_locales => ['en','de'],
custom_properties => {
'failureFactor' => 60,
'revokeRefreshToken' => true,
},
failure_factor => 60,
permanent_lockout => true,
max_failure_wait_seconds => 999,
minimum_quick_login_wait_seconds => 40,
wait_increment_seconds => 10,
quick_login_check_milli_seconds => 10,
max_delta_time_seconds => 3600,
otp_policy_type => 'totp',
otp_policy_algorithm => 'HmacSHA512',
otp_policy_initial_counter => 1,
otp_policy_digits => 8,
otp_policy_period => 30,
otp_policy_code_reusable => true,
web_authn_policy_rp_entity_name => 'Keycloak',
web_authn_policy_signature_algorithms => ['ES256', 'ES384', 'ES512', 'RS256', 'RS384', 'RS512'],
web_authn_policy_rp_id => 'https://example.com',
web_authn_policy_attestation_conveyance_preference => 'direct',
web_authn_policy_authenticator_attachment => 'cross-platform',
web_authn_policy_require_resident_key => 'No',
web_authn_policy_user_verification_requirement => 'required',
web_authn_policy_create_timeout => 600,
web_authn_policy_avoid_same_authenticator_register => true,
web_authn_policy_acceptable_aaguids => ['d1d1d1d1-d1d1-d1d1-d1d1-d1d1d1d1d1d1'],
web_authn_policy_passwordless_rp_entity_name => 'Keycloak',
web_authn_policy_passwordless_signature_algorithms => ['ES256', 'ES384', 'ES512', 'RS256', 'RS384', 'RS512'],
web_authn_policy_passwordless_rp_id => 'https://example.com',
web_authn_policy_passwordless_attestation_conveyance_preference => 'direct',
web_authn_policy_passwordless_authenticator_attachment => 'cross-platform',
web_authn_policy_passwordless_require_resident_key => 'No',
web_authn_policy_passwordless_user_verification_requirement => 'required',
web_authn_policy_passwordless_create_timeout => 600,
web_authn_policy_passwordless_avoid_same_authenticator_register => true,
web_authn_policy_passwordless_acceptable_aaguids => ['d1d1d1d1-d1d1-d1d1-d1d1-d1d1d1d1d1d1'],
}
PUPPET_PP

Expand Down Expand Up @@ -263,10 +295,42 @@ class { 'keycloak': }
expect(data['adminTheme']).to eq('keycloak.v2')
expect(data['emailTheme']).to eq('keycloak.v2')
expect(data['failureFactor']).to eq(60)
expect(data['permanentLockout']).to eq(true)
expect(data['maxFailureWaitSeconds']).to eq(999)
expect(data['minimumQuickLoginWaitSeconds']).to eq(40)
expect(data['waitIncrementSeconds']).to eq(10)
expect(data['quickLoginCheckMilliSeconds']).to eq(10)
expect(data['maxDeltaTimeSeconds']).to eq(3600)
expect(data['revokeRefreshToken']).to eq(true)
expect(data['internationalizationEnabled']).to eq(true)
expect(data['defaultLocale']).to eq('en')
expect(data['supportedLocales']).to eq(['de', 'en'])
expect(data['otpPolicyType']).to eq('totp')
expect(data['otpPolicyAlgorithm']).to eq('HmacSHA512')
expect(data['otpPolicyInitialCounter']).to eq(1)
expect(data['otpPolicyDigits']).to eq(8)
expect(data['otpPolicyPeriod']).to eq(30)
expect(data['otpPolicyCodeReusable']).to eq(true)
expect(data['webAuthnPolicyRpEntityName']).to eq('Keycloak')
expect(data['webAuthnPolicySignatureAlgorithms']).to eq(['ES256', 'ES384', 'ES512', 'RS256', 'RS384', 'RS512'])
expect(data['webAuthnPolicyRpId']).to eq('https://example.com')
expect(data['webAuthnPolicyAttestationConveyancePreference']).to eq('direct')
expect(data['webAuthnPolicyAuthenticatorAttachment']).to eq('cross-platform')
expect(data['webAuthnPolicyRequireResidentKey']).to eq('No')
expect(data['webAuthnPolicyUserVerificationRequirement']).to eq('required')
expect(data['webAuthnPolicyCreateTimeout']).to eq(600)
expect(data['webAuthnPolicyAvoidSameAuthenticatorRegister']).to eq(true)
expect(data['webAuthnPolicyAcceptableAaguids']).to eq(['d1d1d1d1-d1d1-d1d1-d1d1-d1d1d1d1d1d1'])
expect(data['webAuthnPolicyPasswordlessRpEntityName']).to eq('Keycloak')
expect(data['webAuthnPolicyPasswordlessSignatureAlgorithms']).to eq(['ES256', 'ES384', 'ES512', 'RS256', 'RS384', 'RS512'])
expect(data['webAuthnPolicyPasswordlessRpId']).to eq('https://example.com')
expect(data['webAuthnPolicyPasswordlessAttestationConveyancePreference']).to eq('direct')
expect(data['webAuthnPolicyPasswordlessAuthenticatorAttachment']).to eq('cross-platform')
expect(data['webAuthnPolicyPasswordlessRequireResidentKey']).to eq('No')
expect(data['webAuthnPolicyPasswordlessUserVerificationRequirement']).to eq('required')
expect(data['webAuthnPolicyPasswordlessCreateTimeout']).to eq(600)
expect(data['webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister']).to eq(true)
expect(data['webAuthnPolicyPasswordlessAcceptableAaguids']).to eq(['d1d1d1d1-d1d1-d1d1-d1d1-d1d1d1d1d1d1'])
end
end

Expand Down
Loading
Loading