From 3fe638013e7609ef250385477ef1613debe7dfbf Mon Sep 17 00:00:00 2001 From: Ondrej Lukas Date: Thu, 22 Mar 2018 10:55:38 +0100 Subject: [PATCH] Added Elytron Creaper commands --- .../commands/elytron/AbstractAddCustom.java | 128 +++ .../elytron/AddExtensionAndSubsystem.java | 23 + .../elytron/CreateServerSSLContext.java | 447 +++++++++++ .../commands/elytron/CredentialRef.java | 105 +++ .../creaper/commands/elytron/Mechanism.java | 211 +++++ .../creaper/commands/elytron/Property.java | 21 + .../elytron/RemoveExtensionAndSubsystem.java | 23 + .../AddAggregateSecurityEventListener.java | 80 ++ .../elytron/audit/AddFileAuditLog.java | 102 +++ .../AddPeriodicRotatingFileAuditLog.java | 114 +++ .../audit/AddSizeRotatingFileAuditLog.java | 138 ++++ .../elytron/audit/AddSyslogAuditLog.java | 131 +++ .../commands/elytron/audit/AuditFormat.java | 7 + .../AddAuthenticationConfiguration.java | 232 ++++++ .../AddAuthenticationContext.java | 286 +++++++ .../credentialstore/AddCredentialStore.java | 162 ++++ .../AddCredentialStoreAlias.java | 131 +++ .../RemoveCredentialStore.java | 36 + .../RemoveCredentialStoreAlias.java | 47 ++ .../AddCustomCredentialSecurityFactory.java | 54 ++ .../AddKerberosSecurityFactory.java | 194 +++++ .../elytron/dircontext/AddDirContext.java | 208 +++++ .../elytron/domain/AddSecurityDomain.java | 282 +++++++ ...ddAggregateHttpServerMechanismFactory.java | 81 ++ ...onfigurableHttpServerMechanismFactory.java | 173 ++++ .../http/AddHttpAuthenticationFactory.java | 157 ++++ ...AddProviderHttpServerMechanismFactory.java | 72 ++ ...rviceLoaderHttpServerMechanismFactory.java | 73 ++ .../mapper/AbstractAddPrincipalDecoder.java | 66 ++ .../AbstractAddPrincipalTransformer.java | 65 ++ .../mapper/AddAddPrefixRoleMapper.java | 74 ++ .../mapper/AddAddSuffixRoleMapper.java | 74 ++ .../mapper/AddAggregatePrincipalDecoder.java | 50 ++ .../AddAggregatePrincipalTransformer.java | 49 ++ .../mapper/AddAggregateRoleMapper.java | 81 ++ .../AddChainedPrincipalTransformer.java | 49 ++ .../AddConcatenatingPrincipalDecoder.java | 63 ++ .../mapper/AddConstantPermissionMapper.java | 166 ++++ .../mapper/AddConstantPrincipalDecoder.java | 74 ++ .../AddConstantPrincipalTransformer.java | 75 ++ .../mapper/AddConstantRealmMapper.java | 74 ++ .../elytron/mapper/AddConstantRoleMapper.java | 80 ++ .../mapper/AddCustomPermissionMapper.java | 54 ++ .../mapper/AddCustomPrincipalDecoder.java | 54 ++ .../mapper/AddCustomPrincipalTransformer.java | 54 ++ .../elytron/mapper/AddCustomRealmMapper.java | 54 ++ .../elytron/mapper/AddCustomRoleDecoder.java | 54 ++ .../elytron/mapper/AddCustomRoleMapper.java | 32 + .../mapper/AddLogicalPermissionMapper.java | 102 +++ .../elytron/mapper/AddLogicalRoleMapper.java | 97 +++ .../mapper/AddMappedRegexRealmMapper.java | 133 ++++ .../mapper/AddRegexPrincipalTransformer.java | 95 +++ ...ddRegexValidatingPrincipalTransformer.java | 84 ++ .../mapper/AddSimplePermissionMapper.java | 288 +++++++ .../mapper/AddSimpleRegexRealmMapper.java | 82 ++ .../elytron/mapper/AddSimpleRoleDecoder.java | 74 ++ .../AddX500AttributePrincipalDecoder.java | 169 ++++ .../providerloader/AddAggregateProviders.java | 81 ++ .../providerloader/AddProviderLoader.java | 145 ++++ .../elytron/realm/AddAggregateRealm.java | 87 ++ .../elytron/realm/AddCachingRealm.java | 127 +++ .../realm/AddCustomModifiableRealm.java | 54 ++ .../elytron/realm/AddCustomRealm.java | 54 ++ .../elytron/realm/AddFilesystemRealm.java | 105 +++ .../elytron/realm/AddIdentityRealm.java | 101 +++ .../commands/elytron/realm/AddJdbcRealm.java | 585 ++++++++++++++ .../elytron/realm/AddKeyStoreRealm.java | 74 ++ .../commands/elytron/realm/AddLdapRealm.java | 744 ++++++++++++++++++ .../elytron/realm/AddPropertiesRealm.java | 142 ++++ .../commands/elytron/realm/AddTokenRealm.java | 309 ++++++++ .../sasl/AddAggregateSaslServerFactory.java | 81 ++ .../AddConfigurableSaslServerFactory.java | 212 +++++ ...ismProviderFilteringSaslServerFactory.java | 204 +++++ .../sasl/AddProviderSaslServerFactory.java | 73 ++ .../sasl/AddSaslAuthenticationFactory.java | 158 ++++ .../AddServiceLoaderSaslServerFactory.java | 73 ++ .../securityproperty/AddSecurityProperty.java | 58 ++ .../elytron/tls/AbstractAddSSLContext.java | 104 +++ .../elytron/tls/AddClientSSLContext.java | 71 ++ .../elytron/tls/AddFilteringKeyStore.java | 105 +++ .../commands/elytron/tls/AddKeyManager.java | 143 ++++ .../commands/elytron/tls/AddKeyStore.java | 165 ++++ .../commands/elytron/tls/AddLdapKeyStore.java | 399 ++++++++++ .../elytron/tls/AddServerSSLContext.java | 199 +++++ .../commands/elytron/tls/AddTrustManager.java | 220 ++++++ .../AddApplicationSecurityDomain.java | 110 +++ .../AddCustomCredentialSecurityFactory.groovy | 32 + .../mapper/AddCustomPermissionMapper.groovy | 32 + .../mapper/AddCustomPrincipalDecoder.groovy | 32 + .../AddCustomPrincipalTransformer.groovy | 32 + .../mapper/AddCustomRealmMapper.groovy | 32 + .../mapper/AddCustomRoleDecoder.groovy | 32 + .../elytron/mapper/AddCustomRoleMapper.groovy | 32 + .../elytron/realm/AddCachingRealm.groovy | 25 + .../realm/AddCustomModifiableRealm.groovy | 32 + .../elytron/realm/AddCustomRealm.groovy | 32 + .../elytron/tls/AddClientSSLContext.groovy | 34 + .../elytron/tls/AddFilteringKeyStore.groovy | 30 + .../commands/elytron/tls/AddKeyManager.groovy | 40 + .../commands/elytron/tls/AddKeyStore.groovy | 51 ++ .../elytron/tls/AddLdapKeyStore.groovy | 76 ++ .../elytron/tls/AddServerSSLContext.groovy | 46 ++ .../elytron/tls/AddTrustManager.groovy | 44 ++ .../AddApplicationSecurityDomain.groovy | 21 + .../elytron/AbstractAddCustomOfflineTest.java | 276 +++++++ .../elytron/AbstractElytronOnlineTest.java | 140 ++++ .../CreateServerSSLContextOnlineTest.java | 211 +++++ ...regateSecurityEventListenerOnlineTest.java | 209 +++++ .../audit/AddFileAuditLogOnlineTest.java | 144 ++++ ...eriodicRotatingFileAuditLogOnlineTest.java | 192 +++++ ...AddSizeRotatingFileAuditLogOnlineTest.java | 166 ++++ .../audit/AddSyslogAuditLogOnlineTest.java | 238 ++++++ ...AuthenticationConfigurationOnlineTest.java | 357 +++++++++ .../AddAuthenticationContextOnlineTest.java | 244 ++++++ .../AbstractCredentialStoreOnlineTest.java | 56 ++ .../AddCredentialStoreAliasOnlineTest.java | 257 ++++++ .../AddCredentialStoreOnlineTest.java | 243 ++++++ .../RemoveCredentialStoreAliasOnlineTest.java | 152 ++++ .../RemoveCredentialStoreOnlineTest.java | 66 ++ ...mCredentialSecurityFactoryOfflineTest.java | 34 + ...omCredentialSecurityFactoryOnlineTest.java | 66 ++ .../AddKerberosSecurityFactoryOnlineTest.java | 197 +++++ .../dircontext/AddDirContextOnlineTest.java | 260 ++++++ .../domain/AddSecurityDomainOnlineTest.java | 398 ++++++++++ ...eHttpServerMechanismFactoryOnlineTest.java | 221 ++++++ ...eHttpServerMechanismFactoryOnlineTest.java | 230 ++++++ ...ddHttpAuthenticationFactoryOnlineTest.java | 473 +++++++++++ ...rHttpServerMechanismFactoryOnlineTest.java | 138 ++++ ...rHttpServerMechanismFactoryOnlineTest.java | 139 ++++ ...AbstractAddPrincipalDecoderOnlineTest.java | 74 ++ ...ractAddPrincipalTransformerOnlineTest.java | 74 ++ .../AddAddPrefixRoleMapperOnlineTest.java | 103 +++ .../AddAddSuffixRoleMapperOnlineTest.java | 103 +++ ...ddAggregatePrincipalDecoderOnlineTest.java | 165 ++++ ...gregatePrincipalTransformerOnlineTest.java | 171 ++++ .../AddAggregateRoleMapperOnlineTest.java | 202 +++++ ...ChainedPrincipalTransformerOnlineTest.java | 171 ++++ ...ncatenatingPrincipalDecoderOnlineTest.java | 173 ++++ ...AddConstantPermissionMapperOnlineTest.java | 200 +++++ ...AddConstantPrincipalDecoderOnlineTest.java | 138 ++++ ...onstantPrincipalTransformerOnlineTest.java | 143 ++++ .../AddConstantRealmMapperOnlineTest.java | 134 ++++ .../AddConstantRoleMapperOnlineTest.java | 127 +++ .../AddCustomPermissionMapperOfflineTest.java | 34 + .../AddCustomPermissionMapperOnlineTest.java | 64 ++ .../AddCustomPrincipalDecoderOfflineTest.java | 34 + .../AddCustomPrincipalDecoderOnlineTest.java | 65 ++ ...CustomPrincipalTransformerOfflineTest.java | 34 + ...dCustomPrincipalTransformerOnlineTest.java | 65 ++ .../AddCustomRealmMapperOfflineTest.java | 30 + .../AddCustomRealmMapperOnlineTest.java | 65 ++ .../AddCustomRoleDecoderOfflineTest.java | 34 + .../AddCustomRoleDecoderOnlineTest.java | 64 ++ .../AddCustomRoleMapperOfflineTest.java | 30 + .../mapper/AddCustomRoleMapperOnlineTest.java | 65 ++ .../AddLogicalPermissionMapperOnlineTest.java | 191 +++++ .../AddLogicalRoleMapperOnlineTest.java | 144 ++++ .../AddMappedRegexRealmMapperOnlineTest.java | 214 +++++ ...ddRegexPrincipalTransformerOnlineTest.java | 166 ++++ ...idatingPrincipalTransformerOnlineTest.java | 157 ++++ .../AddSimplePermissionMapperOnlineTest.java | 300 +++++++ .../AddSimpleRegexRealmMapperOnlineTest.java | 156 ++++ .../AddSimpleRoleDecoderOnlineTest.java | 129 +++ ...00AttributePrincipalDecoderOnlineTest.java | 211 +++++ .../AddAggregateProvidersOnlineTest.java | 177 +++++ .../providerloader/AddProviderLoaderImpl.java | 17 + .../AddProviderLoaderOnlineTest.java | 254 ++++++ .../realm/AddAggregateRealmOnlineTest.java | 181 +++++ .../realm/AddCachingRealmOfflineTest.java | 215 +++++ .../realm/AddCachingRealmOnlineTest.java | 152 ++++ .../AddCustomModifiableRealmOfflineTest.java | 34 + .../AddCustomModifiableRealmOnlineTest.java | 65 ++ .../realm/AddCustomRealmOfflineTest.java | 34 + .../realm/AddCustomRealmOnlineTest.java | 65 ++ .../realm/AddFilesystemRealmOnlineTest.java | 146 ++++ .../realm/AddIdentityRealmOnlineTest.java | 144 ++++ .../elytron/realm/AddJdbcRealmOnlineTest.java | 496 ++++++++++++ .../realm/AddKeyStoreRealmOnlineTest.java | 131 +++ .../elytron/realm/AddLdapRealmOnlineTest.java | 533 +++++++++++++ .../realm/AddPropertiesRealmOnlineTest.java | 195 +++++ .../realm/AddTokenRealmOnlineTest.java | 363 +++++++++ ...dAggregateSaslServerFactoryOnlineTest.java | 207 +++++ ...nfigurableSaslServerFactoryOnlineTest.java | 255 ++++++ ...rFilteringSaslServerFactoryOnlineTest.java | 246 ++++++ ...ddProviderSaslServerFactoryOnlineTest.java | 130 +++ ...ddSaslAuthenticationFactoryOnlineTest.java | 475 +++++++++++ ...viceLoaderSaslServerFactoryOnlineTest.java | 132 ++++ .../AddSecurityPropertyOnlineTest.java | 103 +++ .../tls/AbstractAddSSLContextOnlineTest.java | 115 +++ .../tls/AddClientSSLContextOfflineTest.java | 250 ++++++ .../tls/AddClientSSLContextOnlineTest.java | 134 ++++ .../tls/AddFilteringKeyStoreOfflineTest.java | 227 ++++++ .../tls/AddFilteringKeyStoreOnlineTest.java | 203 +++++ .../elytron/tls/AddKeyManagerOfflineTest.java | 281 +++++++ .../elytron/tls/AddKeyManagerOnlineTest.java | 255 ++++++ .../elytron/tls/AddKeyStoreOfflineTest.java | 288 +++++++ .../elytron/tls/AddKeyStoreOnlineTest.java | 195 +++++ .../tls/AddLdapKeyStoreOfflineTest.java | 300 +++++++ .../tls/AddLdapKeyStoreOnlineTest.java | 306 +++++++ .../tls/AddServerSSLContextOfflineTest.java | 279 +++++++ .../tls/AddServerSSLContextOnlineTest.java | 246 ++++++ .../tls/AddTrustManagerOfflineTest.java | 266 +++++++ .../tls/AddTrustManagerOnlineTest.java | 185 +++++ ...dApplicationSecurityDomainOfflineTest.java | 240 ++++++ ...ddApplicationSecurityDomainOnlineTest.java | 216 +++++ 205 files changed, 29895 insertions(+) create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/AbstractAddCustom.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/AddExtensionAndSubsystem.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/CreateServerSSLContext.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/CredentialRef.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/Mechanism.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/Property.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/RemoveExtensionAndSubsystem.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/audit/AddAggregateSecurityEventListener.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/audit/AddFileAuditLog.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/audit/AddPeriodicRotatingFileAuditLog.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/audit/AddSizeRotatingFileAuditLog.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/audit/AddSyslogAuditLog.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/audit/AuditFormat.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/authenticationclient/AddAuthenticationConfiguration.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/authenticationclient/AddAuthenticationContext.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/AddCredentialStore.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/AddCredentialStoreAlias.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/RemoveCredentialStore.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/RemoveCredentialStoreAlias.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/credfactory/AddCustomCredentialSecurityFactory.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/credfactory/AddKerberosSecurityFactory.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/dircontext/AddDirContext.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/domain/AddSecurityDomain.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/http/AddAggregateHttpServerMechanismFactory.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/http/AddConfigurableHttpServerMechanismFactory.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/http/AddHttpAuthenticationFactory.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/http/AddProviderHttpServerMechanismFactory.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/http/AddServiceLoaderHttpServerMechanismFactory.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AbstractAddPrincipalDecoder.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AbstractAddPrincipalTransformer.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAddPrefixRoleMapper.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAddSuffixRoleMapper.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAggregatePrincipalDecoder.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAggregatePrincipalTransformer.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAggregateRoleMapper.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddChainedPrincipalTransformer.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConcatenatingPrincipalDecoder.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantPermissionMapper.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantPrincipalDecoder.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantPrincipalTransformer.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantRealmMapper.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantRoleMapper.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPermissionMapper.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalDecoder.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalTransformer.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRealmMapper.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleDecoder.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleMapper.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddLogicalPermissionMapper.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddLogicalRoleMapper.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddMappedRegexRealmMapper.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddRegexPrincipalTransformer.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddRegexValidatingPrincipalTransformer.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddSimplePermissionMapper.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddSimpleRegexRealmMapper.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddSimpleRoleDecoder.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddX500AttributePrincipalDecoder.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/providerloader/AddAggregateProviders.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/providerloader/AddProviderLoader.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddAggregateRealm.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCachingRealm.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomModifiableRealm.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomRealm.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddFilesystemRealm.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddIdentityRealm.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddJdbcRealm.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddKeyStoreRealm.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddLdapRealm.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddPropertiesRealm.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddTokenRealm.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddAggregateSaslServerFactory.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddConfigurableSaslServerFactory.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddMechanismProviderFilteringSaslServerFactory.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddProviderSaslServerFactory.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddSaslAuthenticationFactory.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddServiceLoaderSaslServerFactory.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/securityproperty/AddSecurityProperty.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AbstractAddSSLContext.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AddClientSSLContext.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AddFilteringKeyStore.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyManager.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyStore.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AddLdapKeyStore.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AddServerSSLContext.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AddTrustManager.java create mode 100644 commands/src/main/java/org/wildfly/extras/creaper/commands/undertow/AddApplicationSecurityDomain.java create mode 100644 commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/credfactory/AddCustomCredentialSecurityFactory.groovy create mode 100644 commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPermissionMapper.groovy create mode 100644 commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalDecoder.groovy create mode 100644 commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalTransformer.groovy create mode 100644 commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRealmMapper.groovy create mode 100644 commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleDecoder.groovy create mode 100644 commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleMapper.groovy create mode 100644 commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/realm/AddCachingRealm.groovy create mode 100644 commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomModifiableRealm.groovy create mode 100644 commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomRealm.groovy create mode 100644 commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/tls/AddClientSSLContext.groovy create mode 100644 commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/tls/AddFilteringKeyStore.groovy create mode 100644 commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyManager.groovy create mode 100644 commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyStore.groovy create mode 100644 commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/tls/AddLdapKeyStore.groovy create mode 100644 commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/tls/AddServerSSLContext.groovy create mode 100644 commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/tls/AddTrustManager.groovy create mode 100644 commands/src/main/resources/org/wildfly/extras/creaper/commands/undertow/AddApplicationSecurityDomain.groovy create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/AbstractAddCustomOfflineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/AbstractElytronOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/CreateServerSSLContextOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/audit/AddAggregateSecurityEventListenerOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/audit/AddFileAuditLogOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/audit/AddPeriodicRotatingFileAuditLogOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/audit/AddSizeRotatingFileAuditLogOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/audit/AddSyslogAuditLogOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/authenticationclient/AddAuthenticationConfigurationOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/authenticationclient/AddAuthenticationContextOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/AbstractCredentialStoreOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/AddCredentialStoreAliasOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/AddCredentialStoreOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/RemoveCredentialStoreAliasOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/RemoveCredentialStoreOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credfactory/AddCustomCredentialSecurityFactoryOfflineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credfactory/AddCustomCredentialSecurityFactoryOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credfactory/AddKerberosSecurityFactoryOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/dircontext/AddDirContextOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/domain/AddSecurityDomainOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/http/AddAggregateHttpServerMechanismFactoryOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/http/AddConfigurableHttpServerMechanismFactoryOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/http/AddHttpAuthenticationFactoryOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/http/AddProviderHttpServerMechanismFactoryOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/http/AddServiceLoaderHttpServerMechanismFactoryOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AbstractAddPrincipalDecoderOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AbstractAddPrincipalTransformerOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAddPrefixRoleMapperOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAddSuffixRoleMapperOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAggregatePrincipalDecoderOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAggregatePrincipalTransformerOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAggregateRoleMapperOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddChainedPrincipalTransformerOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConcatenatingPrincipalDecoderOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantPermissionMapperOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantPrincipalDecoderOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantPrincipalTransformerOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantRealmMapperOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantRoleMapperOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPermissionMapperOfflineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPermissionMapperOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalDecoderOfflineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalDecoderOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalTransformerOfflineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalTransformerOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRealmMapperOfflineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRealmMapperOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleDecoderOfflineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleDecoderOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleMapperOfflineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleMapperOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddLogicalPermissionMapperOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddLogicalRoleMapperOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddMappedRegexRealmMapperOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddRegexPrincipalTransformerOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddRegexValidatingPrincipalTransformerOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddSimplePermissionMapperOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddSimpleRegexRealmMapperOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddSimpleRoleDecoderOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddX500AttributePrincipalDecoderOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/providerloader/AddAggregateProvidersOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/providerloader/AddProviderLoaderImpl.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/providerloader/AddProviderLoaderOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddAggregateRealmOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCachingRealmOfflineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCachingRealmOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomModifiableRealmOfflineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomModifiableRealmOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomRealmOfflineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomRealmOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddFilesystemRealmOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddIdentityRealmOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddJdbcRealmOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddKeyStoreRealmOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddLdapRealmOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddPropertiesRealmOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddTokenRealmOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddAggregateSaslServerFactoryOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddConfigurableSaslServerFactoryOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddMechanismProviderFilteringSaslServerFactoryOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddProviderSaslServerFactoryOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddSaslAuthenticationFactoryOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddServiceLoaderSaslServerFactoryOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/securityproperty/AddSecurityPropertyOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AbstractAddSSLContextOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddClientSSLContextOfflineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddClientSSLContextOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddFilteringKeyStoreOfflineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddFilteringKeyStoreOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyManagerOfflineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyManagerOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyStoreOfflineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyStoreOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddLdapKeyStoreOfflineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddLdapKeyStoreOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddServerSSLContextOfflineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddServerSSLContextOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddTrustManagerOfflineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddTrustManagerOnlineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/undertow/AddApplicationSecurityDomainOfflineTest.java create mode 100644 testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/undertow/AddApplicationSecurityDomainOnlineTest.java diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/AbstractAddCustom.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/AbstractAddCustom.java new file mode 100644 index 00000000..f51f3822 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/AbstractAddCustom.java @@ -0,0 +1,128 @@ +package org.wildfly.extras.creaper.commands.elytron; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.wildfly.extras.creaper.commands.foundation.offline.xml.GroovyXmlTransform; +import org.wildfly.extras.creaper.commands.foundation.offline.xml.Subtree; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.offline.OfflineCommand; +import org.wildfly.extras.creaper.core.offline.OfflineCommandContext; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public abstract class AbstractAddCustom implements OnlineCommand, OfflineCommand { + + private final String name; + private final String className; + private final String module; + private final Map configuration; + private final boolean replaceExisting; + + protected AbstractAddCustom(Builder builder) { + this.name = builder.name; + this.className = builder.className; + this.module = builder.module; + this.configuration = builder.configuration; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public final void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address address = Address.subsystem("elytron").and(getCustomTypeName(), name); + if (replaceExisting) { + ops.removeIfExists(address); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(address, Values.empty() + .and("class-name", className) + .and("module", module) + .andObjectOptional("configuration", Values.fromMap(configuration))); + } + + @Override + public final void apply(OfflineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + ctx.client.apply(getGroovyBuilder() + .subtree("elytronSubsystem", Subtree.subsystem("elytron")) + .parameter("atrName", name) + .parameter("atrClassName", className) + .parameter("atrModule", module) + .parameter("atrConfiguration", configuration) + .parameter("atrReplaceExisting", replaceExisting) + .build()); + } + + protected abstract GroovyXmlTransform.Builder getGroovyBuilder(); + + protected abstract String getCustomTypeName(); + + protected abstract static class Builder { + + private final String name; + protected String className; + protected String module; + private Map configuration = new LinkedHashMap(); + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the custom-realm-mapper must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the custom-realm-mapper must not be empty value"); + } + + this.name = name; + } + + public abstract S build(); + + public final T className(String className) { + this.className = className; + return (T) this; + } + + public final T module(String module) { + this.module = module; + return (T) this; + } + + public final T addConfiguration(String name, String value) { + configuration.put(name, value); + return (T) this; + } + + public final T addConfiguration(String name, boolean value) { + configuration.put(name, Boolean.toString(value)); + return (T) this; + } + + public final T replaceExisting() { + this.replaceExisting = true; + return (T) this; + } + + protected final void checkClassNameAndModule() { + if (className == null || className.isEmpty()) { + throw new IllegalArgumentException("className must not be null or empty string"); + } + if (module == null || module.isEmpty()) { + throw new IllegalArgumentException("module must not be null or empty string"); + } + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/AddExtensionAndSubsystem.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/AddExtensionAndSubsystem.java new file mode 100644 index 00000000..6ef1096f --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/AddExtensionAndSubsystem.java @@ -0,0 +1,23 @@ +package org.wildfly.extras.creaper.commands.elytron; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddExtensionAndSubsystem implements OnlineCommand { + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + Operations ops = new Operations(ctx.client); + ops.add(Address.extension("org.wildfly.extension.elytron")); + ops.add(Address.subsystem("elytron")); + new Administration(ctx.client).reloadIfRequired(); + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/CreateServerSSLContext.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/CreateServerSSLContext.java new file mode 100644 index 00000000..4603bb73 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/CreateServerSSLContext.java @@ -0,0 +1,447 @@ +package org.wildfly.extras.creaper.commands.elytron; + +import java.util.Arrays; +import java.util.List; + +import org.wildfly.extras.creaper.commands.elytron.CredentialRef.CredentialRefBuilder; +import org.wildfly.extras.creaper.commands.elytron.tls.AddKeyManager; +import org.wildfly.extras.creaper.commands.elytron.tls.AddKeyStore; +import org.wildfly.extras.creaper.commands.elytron.tls.AddServerSSLContext; +import org.wildfly.extras.creaper.commands.elytron.tls.AddTrustManager; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; + +/** + * Composite creaper command. Takes flat parameters and compose server ssl + * context with all dependent resource hierarchy. + * + *

+ * It should be possible to configure most of use cases atomic creaper commands + * allows. + *

+ * + */ +public class CreateServerSSLContext implements OnlineCommand { + + private static final String KEY_STORE_NAME = "key-store-name"; + private static final String TRUST_STORE_NAME = "trust-store-name"; + private static final String KEY_MANAGER_NAME = "key-manager-name"; + private static final String TRUST_MANAGER_NAME = "trust-manager-name"; + + // SSL Context + private final String name; + protected final List protocols; + private final String cipherSuiteFilter; + private final Boolean needClientAuth; + private final Boolean wantClientAuth; + private final Boolean authenticationOptional; + private final String securityDomain; + private final Integer maximumSessionCacheSize; + private final Integer sessionTimeout; + private final String providers; + // Keystore + private final String keyStoreType; + private final String keyStorePath; + private final String keyStorePassword; + private final String keyPassword; + private final String keyStoreAlias; + private final String keyStoreRelativeTo; + private final Boolean keyStoreRequired; + private final String keyStoreProviders; + private final String keyManagerProviders; + // Truststore + private final String trustStoreType; + private final String trustStorePath; + private final String trustStorePassword; + private final String trustStoreAlias; + private final String trustStoreRelativeTo; + private final Boolean trustStoreRequired; + private final String trustStoreProviders; + private final String trustManagerProviders; + + // Multiple usage + private final String algorithm; // keystore manager, truststore manager + + + private CreateServerSSLContext(Builder builder) { + this.name = builder.name; + this.keyStoreType = builder.keyStoreType; + this.keyStorePath = builder.keyStorePath; + this.keyStorePassword = builder.keyStorePassword; + this.keyPassword = builder.keyPassword; + this.trustStoreType = builder.trustStoreType; + this.trustStorePath = builder.trustStorePath; + this.trustStorePassword = builder.trustStorePassword; + this.protocols = builder.protocols; + this.cipherSuiteFilter = builder.cipherSuiteFilter; + this.needClientAuth = builder.needClientAuth; + this.wantClientAuth = builder.wantClientAuth; + this.authenticationOptional = builder.authenticationOptional; + this.securityDomain = builder.securityDomain; + this.maximumSessionCacheSize = builder.maximumSessionCacheSize; + this.sessionTimeout = builder.sessionTimeout; + this.keyStoreAlias = builder.keyStoreAlias; + this.keyStoreRelativeTo = builder.keyStoreRelativeTo; + this.keyStoreRequired = builder.keyStoreRequired; + this.trustStoreAlias = builder.trustStoreAlias; + this.trustStoreRelativeTo = builder.trustStoreRelativeTo; + this.trustStoreRequired = builder.trustStoreRequired; + this.algorithm = builder.algorithm; + this.trustStoreProviders = builder.trustStoreProviders; + this.keyStoreProviders = builder.keyStoreProviders; + this.keyManagerProviders = builder.keyManagerProviders; + this.trustManagerProviders = builder.trustManagerProviders; + this.providers = builder.providers; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + + AddKeyStore addKeyStore = new AddKeyStore.Builder(getUniqueName(KEY_STORE_NAME)) + .type(keyStoreType) + .path(keyStorePath) + .relativeTo(keyStoreRelativeTo) + .required(keyStoreRequired) + .aliasFilter(keyStoreAlias) + .providers(keyStoreProviders) + .credentialReference(new CredentialRefBuilder() + .clearText(keyStorePassword) + .build()) + .build(); + + + AddKeyManager addKeyManager = new AddKeyManager.Builder(getUniqueName(KEY_MANAGER_NAME)) + .keyStore(getUniqueName(KEY_STORE_NAME)) + .algorithm(algorithm) + .providers(keyManagerProviders) + .credentialReference(new CredentialRefBuilder() + .clearText(keyPassword) + .build()) + .build(); + + AddKeyStore addTrustStore = null; + AddTrustManager addTrustManager = null; + // Trust Store is optional + if (isTrustStoreConfigured()) { + addTrustStore = new AddKeyStore.Builder(getUniqueName(TRUST_STORE_NAME)) + .type(trustStoreType) + .path(trustStorePath) + .relativeTo(trustStoreRelativeTo) + .required(trustStoreRequired) + .aliasFilter(trustStoreAlias) + .providers(trustStoreProviders) + .credentialReference(new CredentialRefBuilder() + .clearText(trustStorePassword) + .build()) + .build(); + + addTrustManager = new AddTrustManager.Builder(getUniqueName(TRUST_MANAGER_NAME)) + .algorithm(algorithm) + .providers(trustManagerProviders) + .keyStore(getUniqueName(TRUST_STORE_NAME)) + .build(); + } + + AddServerSSLContext.Builder sslServerContextBuilder = new AddServerSSLContext.Builder(name) + .protocols((protocols == null) ? null : protocols.toArray(new String[protocols.size()])) + .cipherSuiteFilter(cipherSuiteFilter) + .needClientAuth(needClientAuth) + .sessionTimeout(sessionTimeout) + .maximumSessionCacheSize(maximumSessionCacheSize) + .securityDomain(securityDomain) + .authenticationOptional(authenticationOptional) + .wantClientAuth(wantClientAuth) + .providers(providers) + .keyManager(getUniqueName(KEY_MANAGER_NAME)); + + if (isTrustStoreConfigured()) { + sslServerContextBuilder + .trustManager(getUniqueName(TRUST_MANAGER_NAME)); + } + + ctx.client.apply(addKeyStore); + ctx.client.apply(addKeyManager); + if (isTrustStoreConfigured()) { + ctx.client.apply(addTrustStore); + ctx.client.apply(addTrustManager); + } + ctx.client.apply(sslServerContextBuilder.build()); + } + + /** + * Get name of trust manager associated with server ssl context. + * + * @param serverSslContextName server SSL context name + * @return trust manager name + */ + public static String getTrustManagerName(String serverSslContextName) { + return getUniqueName(TRUST_MANAGER_NAME, serverSslContextName); + } + + /** + * Get name of key manager associated with server ssl context. + * + * @param serverSslContextName server SSL context name + * @return key manager name + */ + public static String getKeyManagerName(String serverSslContextName) { + return getUniqueName(KEY_MANAGER_NAME, serverSslContextName); + } + + /** + * Get name of key store associated with server ssl context. + * + * @param serverSslContext server SSL context name + * @return key store name + */ + public static String getKeyStoreName(String serverSslContext) { + return getUniqueName(KEY_STORE_NAME, serverSslContext); + } + + /** + * Get name of trust store associated with server ssl context. + * + * @param serverSslContext server SSL context name + * @return trust store name + */ + public static String getTrustStoreName(String serverSslContext) { + return getUniqueName(TRUST_STORE_NAME, serverSslContext); + } + + /** + * @return if trust store is configured or not + */ + private boolean isTrustStoreConfigured() { + return trustStorePassword != null && !trustStorePassword.isEmpty(); + } + + /** + * It will generate unique name by adding name of server ssl context. + * + *

+ * It is ensured server ssl context has to be unique. + *

+ * + * @param resourceNameBase , e.g. key-store + * @return name suffixed with ssl context name + */ + private String getUniqueName(String resourceNameBase) { + return getUniqueName(resourceNameBase, this.name); + } + + private static String getUniqueName(String resourceNameBase, String sslContextName) { + return resourceNameBase + "_" + sslContextName; + } + + public static final class Builder { + + // SSL Context + private String name; + private List protocols; + private String cipherSuiteFilter; + private Boolean needClientAuth; + private Boolean wantClientAuth; + private Boolean authenticationOptional; + private String securityDomain; + private Integer maximumSessionCacheSize; + private Integer sessionTimeout; + private String providers; + // Keystore + private String keyStoreType = "JKS"; + private String keyStorePath; + private String keyStorePassword; + private String keyPassword; + private String keyStoreAlias; + private String keyStoreRelativeTo; + private Boolean keyStoreRequired; + private String keyStoreProviders; + private String keyManagerProviders; + // Truststore + private String trustStoreType = "JKS"; + private String trustStorePath; + private String trustStorePassword; + private String trustStoreAlias; + private String trustStoreRelativeTo; + private Boolean trustStoreRequired; + private String trustStoreProviders; + private String trustManagerProviders; + // Multiple usage + private String algorithm; // keystore manager, truststore manager + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the ssl-context must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the ssl-context must not be empty value"); + } + this.name = name; + } + + public Builder keyStoreType(String keyStoreType) { + this.keyStoreType = keyStoreType; + return this; + } + + public Builder keyStorePath(String keyStorePath) { + this.keyStorePath = keyStorePath; + return this; + } + + public Builder keyStorePassword(String keyStorePassword) { + this.keyStorePassword = keyStorePassword; + return this; + } + + public Builder keyPassword(String keyPassword) { + this.keyPassword = keyPassword; + return this; + } + + public Builder trustStoreType(String trustStoreType) { + this.trustStoreType = trustStoreType; + return this; + } + + public Builder trustStorePath(String trustStorePath) { + this.trustStorePath = trustStorePath; + return this; + } + + public Builder trustStorePassword(String trustStorePassword) { + this.trustStorePassword = trustStorePassword; + return this; + } + + public Builder protocols(String... protocols) { + if (protocols != null && protocols.length > 0) { + this.protocols = Arrays.asList(protocols); + } + return this; + } + + public Builder cipherSuiteFilter(String cipherSuiteFilter) { + this.cipherSuiteFilter = cipherSuiteFilter; + return this; + } + + public Builder needClientAuth(Boolean needClientAuth) { + this.needClientAuth = needClientAuth; + return this; + } + + public Builder wantClientAuth(Boolean wantClientAuth) { + this.wantClientAuth = wantClientAuth; + return this; + } + + public Builder authenticationOptional(Boolean authenticationOptional) { + this.authenticationOptional = authenticationOptional; + return this; + } + + public Builder securityDomain(String securityDomain) { + this.securityDomain = securityDomain; + return this; + } + + public Builder maximumSessionCacheSize(Integer maximumSessionCacheSize) { + this.maximumSessionCacheSize = maximumSessionCacheSize; + return this; + } + + public Builder sessionTimeout(Integer sessionTimeout) { + this.sessionTimeout = sessionTimeout; + return this; + } + + public Builder keyStoreAlias(String keyStoreAlias) { + this.keyStoreAlias = keyStoreAlias; + return this; + } + + public Builder keyStoreRelativeTo(String keyStoreRelativeTo) { + this.keyStoreRelativeTo = keyStoreRelativeTo; + return this; + } + + public Builder keyStoreRequired(Boolean keyStoreRequired) { + this.keyStoreRequired = keyStoreRequired; + return this; + } + + public Builder trustStoreAlias(String trustStoreAlias) { + this.trustStoreAlias = trustStoreAlias; + return this; + } + + public Builder trustStoreRelativeTo(String trustStoreRelativeTo) { + this.trustStoreRelativeTo = trustStoreRelativeTo; + return this; + } + + public Builder trustStoreRequired(Boolean trustStoreRequired) { + this.trustStoreRequired = trustStoreRequired; + return this; + } + + public Builder algorithm(String algorithm) { + this.algorithm = algorithm; + return this; + } + + public Builder trustStoreProviders(String trustStoreProviders) { + this.trustStoreProviders = trustStoreProviders; + return this; + } + + public Builder keyStoreProviders(String keyStoreProviders) { + this.keyStoreProviders = keyStoreProviders; + return this; + } + + public Builder keyManagerProviders(String keyManagerProviders) { + this.keyManagerProviders = keyManagerProviders; + return this; + } + + public Builder trustManagerProviders(String trustManagerProviders) { + this.trustManagerProviders = trustManagerProviders; + return this; + } + + public Builder providers(String providers) { + this.providers = providers; + return this; + } + + /** + * Set this providers to all server ssl context resources which can + * specify that (key-store, key-manager, trust-manager) + * + * @param providersAll + * - providers to ser + * @return builder instance + */ + public Builder providersAll(String providersAll) { + this.keyStoreProviders = providersAll; + this.trustStoreProviders = providersAll; + this.keyManagerProviders = providersAll; + this.trustManagerProviders = providersAll; + this.providers = providersAll; + return this; + } + + public CreateServerSSLContext build() { + if (keyStorePassword == null || keyStorePassword.isEmpty()) { + throw new IllegalArgumentException("Key store password of the ssl-context must not be empty value"); + } + if (keyPassword == null || keyPassword.isEmpty()) { + throw new IllegalArgumentException("Key store item password of the ssl-context must not be empty value"); + } + return new CreateServerSSLContext(this); + } + + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/CredentialRef.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/CredentialRef.java new file mode 100644 index 00000000..69ab00ee --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/CredentialRef.java @@ -0,0 +1,105 @@ +package org.wildfly.extras.creaper.commands.elytron; + +import java.util.HashMap; +import java.util.Map; +import org.wildfly.extras.creaper.core.online.operations.Values; + +public final class CredentialRef { + private String alias; + private String type; + private String store; + private String clearText; + + private CredentialRef(CredentialRefBuilder builder) { + this.alias = builder.alias; + this.type = builder.type; + this.store = builder.store; + this.clearText = builder.clearText; + } + + public String getAlias() { + return alias; + } + + public void setAlias(String alias) { + this.alias = alias; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getStore() { + return store; + } + + public void setStore(String store) { + this.store = store; + } + + public String getClearText() { + return clearText; + } + + public void setClearText(String clearText) { + this.clearText = clearText; + } + + public Values toValues() { + return Values.empty() + .andOptional("alias", getAlias()) + .andOptional("type", getType()) + .andOptional("store", getStore()) + .andOptional("clear-text", getClearText()); + } + + public Map toParameters() { + Map parameters = new HashMap(); + parameters.put("atrCredentialRefAlias", alias); + parameters.put("atrCredentialRefType", type); + parameters.put("atrCredentialRefStore", store); + parameters.put("atrCredentialRefClearText", clearText); + return parameters; + } + + public static final class CredentialRefBuilder { + private String alias; + private String type; + private String store; + private String clearText; + + public CredentialRefBuilder alias(String alias) { + this.alias = alias; + return this; + } + + public CredentialRefBuilder type(String type) { + this.type = type; + return this; + } + + public CredentialRefBuilder store(String store) { + this.store = store; + return this; + } + + public CredentialRefBuilder clearText(String clearText) { + this.clearText = clearText; + return this; + } + + public CredentialRef build() { + if (clearText == null || clearText.isEmpty()) { + if ((alias == null || alias.isEmpty()) || (store == null || store.isEmpty())) { + throw new IllegalArgumentException("Either clear-text, or alias & store must be specified as non empty value"); + } + } + + return new CredentialRef(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/Mechanism.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/Mechanism.java new file mode 100644 index 00000000..4880b5ce --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/Mechanism.java @@ -0,0 +1,211 @@ +package org.wildfly.extras.creaper.commands.elytron; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public final class Mechanism { + + private final String mechanismName; + private final String hostName; + private final String protocol; + private final String preRealmPrincipalTransformer; + private final String postRealmPrincipalTransformer; + private final String finalPrincipalTransformer; + private final String realmMapper; + private final String credentialSecurityFactory; + private final List mechanismRealmConfigurations; + + private Mechanism(Builder builder) { + this.mechanismName = builder.mechanismName; + this.hostName = builder.hostName; + this.protocol = builder.protocol; + this.preRealmPrincipalTransformer = builder.preRealmPrincipalTransformer; + this.postRealmPrincipalTransformer = builder.postRealmPrincipalTransformer; + this.finalPrincipalTransformer = builder.finalPrincipalTransformer; + this.realmMapper = builder.realmMapper; + this.credentialSecurityFactory = builder.credentialSecurityFactory; + this.mechanismRealmConfigurations = builder.mechanismRealmConfigurations; + } + + public String getMechanismName() { + return mechanismName; + } + + public String getHostName() { + return hostName; + } + + public String getProtocol() { + return protocol; + } + + public String getPreRealmPrincipalTransformer() { + return preRealmPrincipalTransformer; + } + + public String getPostRealmPrincipalTransformer() { + return postRealmPrincipalTransformer; + } + + public String getFinalPrincipalTransformer() { + return finalPrincipalTransformer; + } + + public String getRealmMapper() { + return realmMapper; + } + + public String getCredentialSecurityFactory() { + return credentialSecurityFactory; + } + + public List getMechanismRealmConfigurations() { + return mechanismRealmConfigurations; + } + + public static final class Builder { + + private String mechanismName; + private String hostName; + private String protocol; + private String preRealmPrincipalTransformer; + private String postRealmPrincipalTransformer; + private String finalPrincipalTransformer; + private String realmMapper; + private String credentialSecurityFactory; + private List mechanismRealmConfigurations = new ArrayList(); + + public Builder mechanismName(String mechanismName) { + this.mechanismName = mechanismName; + return this; + } + + public Builder hostName(String hostName) { + this.hostName = hostName; + return this; + } + + public Builder protocol(String protocol) { + this.protocol = protocol; + return this; + } + + public Builder preRealmPrincipalTransformer(String preRealmPrincipalTransformer) { + this.preRealmPrincipalTransformer = preRealmPrincipalTransformer; + return this; + } + + public Builder postRealmPrincipalTransformer(String postRealmPrincipalTransformer) { + this.postRealmPrincipalTransformer = postRealmPrincipalTransformer; + return this; + } + + public Builder finalPrincipalTransformer(String finalPrincipalTransformer) { + this.finalPrincipalTransformer = finalPrincipalTransformer; + return this; + } + + public Builder realmMapper(String realmMapper) { + this.realmMapper = realmMapper; + return this; + } + + public Builder credentialSecurityFactory(String credentialSecurityFactory) { + this.credentialSecurityFactory = credentialSecurityFactory; + return this; + } + + public Builder addMechanismRealmConfigurations(MechanismRealm... mechanismRealms) { + if (mechanismRealms == null) { + throw new IllegalArgumentException("mechanism-realm-configuration added must not be null"); + } + Collections.addAll(this.mechanismRealmConfigurations, mechanismRealms); + return this; + } + + public Mechanism build() { + return new Mechanism(this); + } + + } + + public static final class MechanismRealm { + + private final String realmName; + private final String preRealmPrincipalTransformer; + private final String postRealmPrincipalTransformer; + private final String finalPrincipalTransformer; + private final String realmMapper; + + private MechanismRealm(MechanismRealmBuilder builder) { + this.realmName = builder.realmName; + this.preRealmPrincipalTransformer = builder.preRealmPrincipalTransformer; + this.postRealmPrincipalTransformer = builder.postRealmPrincipalTransformer; + this.finalPrincipalTransformer = builder.finalPrincipalTransformer; + this.realmMapper = builder.realmMapper; + } + + public String getRealmName() { + return realmName; + } + + public String getPreRealmPrincipalTransformer() { + return preRealmPrincipalTransformer; + } + + public String getPostRealmPrincipalTransformer() { + return postRealmPrincipalTransformer; + } + + public String getFinalPrincipalTransformer() { + return finalPrincipalTransformer; + } + + public String getRealmMapper() { + return realmMapper; + } + + } + + public static final class MechanismRealmBuilder { + + private String realmName; + private String preRealmPrincipalTransformer; + private String postRealmPrincipalTransformer; + private String finalPrincipalTransformer; + private String realmMapper; + + public MechanismRealmBuilder realmName(String realmName) { + this.realmName = realmName; + return this; + } + + public MechanismRealmBuilder preRealmPrincipalTransformer(String preRealmPrincipalTransformer) { + this.preRealmPrincipalTransformer = preRealmPrincipalTransformer; + return this; + } + + public MechanismRealmBuilder postRealmPrincipalTransformer(String postRealmPrincipalTransformer) { + this.postRealmPrincipalTransformer = postRealmPrincipalTransformer; + return this; + } + + public MechanismRealmBuilder finalPrincipalTransformer(String finalPrincipalTransformer) { + this.finalPrincipalTransformer = finalPrincipalTransformer; + return this; + } + + public MechanismRealmBuilder realmMapper(String realmMapper) { + this.realmMapper = realmMapper; + return this; + } + + public MechanismRealm build() { + if (realmName == null || realmName.isEmpty()) { + throw new IllegalArgumentException("realm-name of mechanism realm must not be null and must include at least one entry"); + } + return new MechanismRealm(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/Property.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/Property.java new file mode 100644 index 00000000..c9616bba --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/Property.java @@ -0,0 +1,21 @@ +package org.wildfly.extras.creaper.commands.elytron; + +public final class Property { + + private final String key; + private final String value; + + public Property(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public String getValue() { + return value; + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/RemoveExtensionAndSubsystem.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/RemoveExtensionAndSubsystem.java new file mode 100644 index 00000000..13721eee --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/RemoveExtensionAndSubsystem.java @@ -0,0 +1,23 @@ +package org.wildfly.extras.creaper.commands.elytron; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class RemoveExtensionAndSubsystem implements OnlineCommand { + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + Operations ops = new Operations(ctx.client); + ops.remove(Address.subsystem("elytron")); + ops.remove(Address.extension("org.wildfly.extension.elytron")); + new Administration(ctx.client).reloadIfRequired(); + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/audit/AddAggregateSecurityEventListener.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/audit/AddAggregateSecurityEventListener.java new file mode 100644 index 00000000..cc85e9ab --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/audit/AddAggregateSecurityEventListener.java @@ -0,0 +1,80 @@ +package org.wildfly.extras.creaper.commands.elytron.audit; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddAggregateSecurityEventListener implements OnlineCommand { + + private final String name; + private final List securityEventListenerList; + private final boolean replaceExisting; + + private AddAggregateSecurityEventListener(Builder builder) { + this.name = builder.name; + this.securityEventListenerList = builder.securityEventListenerList; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address listenerAddress = Address.subsystem("elytron").and("aggregate-security-event-listener", name); + if (replaceExisting) { + ops.removeIfExists(listenerAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(listenerAddress, Values.empty() + .andList(String.class, "security-event-listeners", securityEventListenerList)); + } + + public static final class Builder { + + private final String name; + private List securityEventListenerList = new ArrayList(); + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the aggregate-security-event-listener must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the aggregate-security-event-listener must not be empty value"); + } + + this.name = name; + } + + public Builder addSecurityEventListeners(String... securityEventListeners) { + if (securityEventListeners == null) { + throw new IllegalArgumentException("Listeners added to aggregate-security-event-listener must not be null"); + } + Collections.addAll(this.securityEventListenerList, securityEventListeners); + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddAggregateSecurityEventListener build() { + if (securityEventListenerList == null || securityEventListenerList.size() < 2) { + throw new IllegalArgumentException("Security-event-listener must not be null and must include at least two entries"); + } + return new AddAggregateSecurityEventListener(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/audit/AddFileAuditLog.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/audit/AddFileAuditLog.java new file mode 100644 index 00000000..3e310c49 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/audit/AddFileAuditLog.java @@ -0,0 +1,102 @@ +package org.wildfly.extras.creaper.commands.elytron.audit; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddFileAuditLog implements OnlineCommand { + + private final String name; + private final String path; + private final String relativeTo; + private final Boolean paramSynchronized; + private final AuditFormat format; + private final boolean replaceExisting; + + private AddFileAuditLog(Builder builder) { + this.name = builder.name; + this.path = builder.path; + this.relativeTo = builder.relativeTo; + this.paramSynchronized = builder.paramSynchronized; + this.format = builder.format; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address fileAuditAddress = Address.subsystem("elytron").and("file-audit-log", name); + if (replaceExisting) { + ops.removeIfExists(fileAuditAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(fileAuditAddress, Values.empty() + .and("path", path) + .andOptional("relative-to", relativeTo) + .andOptional("synchronized", paramSynchronized) + .andOptional("format", format == null ? null : format.name())); + } + + public static final class Builder { + + private final String name; + private String path; + private String relativeTo; + private Boolean paramSynchronized; + private AuditFormat format; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the file-audit-log must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the file-audit-log must not be empty value"); + } + this.name = name; + } + + public Builder path(String path) { + this.path = path; + return this; + } + + public Builder relativeTo(String relativeTo) { + this.relativeTo = relativeTo; + return this; + } + + public Builder paramSynchronized(boolean paramSynchronized) { + this.paramSynchronized = paramSynchronized; + return this; + } + + public Builder format(AuditFormat format) { + this.format = format; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddFileAuditLog build() { + if (path == null || path.isEmpty()) { + throw new IllegalArgumentException("Path must not be null and must have a minimum length of 1 character"); + } + + return new AddFileAuditLog(this); + } + + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/audit/AddPeriodicRotatingFileAuditLog.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/audit/AddPeriodicRotatingFileAuditLog.java new file mode 100644 index 00000000..7c2e0fc9 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/audit/AddPeriodicRotatingFileAuditLog.java @@ -0,0 +1,114 @@ +package org.wildfly.extras.creaper.commands.elytron.audit; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddPeriodicRotatingFileAuditLog implements OnlineCommand { + + private final String name; + private final String path; + private final String relativeTo; + private final Boolean paramSynchronized; + private final AuditFormat format; + private final String suffix; + private final boolean replaceExisting; + + private AddPeriodicRotatingFileAuditLog(Builder builder) { + this.name = builder.name; + this.path = builder.path; + this.relativeTo = builder.relativeTo; + this.paramSynchronized = builder.paramSynchronized; + this.format = builder.format; + this.suffix = builder.suffix; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address fileAuditAddress = Address.subsystem("elytron").and("periodic-rotating-file-audit-log", name); + if (replaceExisting) { + ops.removeIfExists(fileAuditAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(fileAuditAddress, Values.empty() + .and("path", path) + .and("suffix", suffix) + .andOptional("relative-to", relativeTo) + .andOptional("synchronized", paramSynchronized) + .andOptional("format", format == null ? null : format.name())); + } + + public static final class Builder { + + private final String name; + private String path; + private String relativeTo; + private Boolean paramSynchronized; + private AuditFormat format; + private String suffix; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the periodic-rotating-file-audit-log must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the periodic-rotating-file-audit-log must not be empty value"); + } + this.name = name; + } + + public Builder path(String path) { + this.path = path; + return this; + } + + public Builder relativeTo(String relativeTo) { + this.relativeTo = relativeTo; + return this; + } + + public Builder paramSynchronized(boolean paramSynchronized) { + this.paramSynchronized = paramSynchronized; + return this; + } + + public Builder format(AuditFormat format) { + this.format = format; + return this; + } + + public Builder suffix(String suffix) { + this.suffix = suffix; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddPeriodicRotatingFileAuditLog build() { + if (path == null || path.isEmpty()) { + throw new IllegalArgumentException("Path must not be null and must have a minimum length of 1 character"); + } + if (suffix == null || suffix.isEmpty()) { + throw new IllegalArgumentException("Suffix must not be null and must have a minimum length of 1 character"); + } + + return new AddPeriodicRotatingFileAuditLog(this); + } + + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/audit/AddSizeRotatingFileAuditLog.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/audit/AddSizeRotatingFileAuditLog.java new file mode 100644 index 00000000..2422d425 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/audit/AddSizeRotatingFileAuditLog.java @@ -0,0 +1,138 @@ +package org.wildfly.extras.creaper.commands.elytron.audit; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddSizeRotatingFileAuditLog implements OnlineCommand { + + private final String name; + private final String path; + private final String relativeTo; + private final Boolean paramSynchronized; + private final AuditFormat format; + private final String suffix; + private final String rotateSize; + private final Long maxBackupIndex; + private final Boolean rotateOnBoot; + private final boolean replaceExisting; + + private AddSizeRotatingFileAuditLog(Builder builder) { + this.name = builder.name; + this.path = builder.path; + this.relativeTo = builder.relativeTo; + this.paramSynchronized = builder.paramSynchronized; + this.format = builder.format; + this.suffix = builder.suffix; + this.replaceExisting = builder.replaceExisting; + this.rotateSize = builder.rotateSize; + this.maxBackupIndex = builder.maxBackupIndex; + this.rotateOnBoot = builder.rotateOnBoot; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address fileAuditAddress = Address.subsystem("elytron").and("size-rotating-file-audit-log", name); + if (replaceExisting) { + ops.removeIfExists(fileAuditAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(fileAuditAddress, Values.empty() + .and("path", path) + .andOptional("suffix", suffix) + .andOptional("max-backup-index", maxBackupIndex) + .andOptional("rotate-on-boot", rotateOnBoot) + .andOptional("rotate-size", rotateSize) + .andOptional("relative-to", relativeTo) + .andOptional("synchronized", paramSynchronized) + .andOptional("format", format == null ? null : format.name())); + } + + public static final class Builder { + + private final String name; + private String path; + private String relativeTo; + private Boolean paramSynchronized; + private AuditFormat format; + private String suffix; + private String rotateSize; + private Long maxBackupIndex; + private Boolean rotateOnBoot; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the size-rotating-file-audit-log must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the size-rotating-file-audit-log must not be empty value"); + } + this.name = name; + } + + public Builder path(String path) { + this.path = path; + return this; + } + + public Builder relativeTo(String relativeTo) { + this.relativeTo = relativeTo; + return this; + } + + public Builder paramSynchronized(boolean paramSynchronized) { + this.paramSynchronized = paramSynchronized; + return this; + } + + public Builder format(AuditFormat format) { + this.format = format; + return this; + } + + public Builder suffix(String suffix) { + this.suffix = suffix; + return this; + } + + public Builder rotateSize(String rotateSize) { + this.rotateSize = rotateSize; + return this; + } + + public Builder maxBackupIndex(long maxBackupIndex) { + this.maxBackupIndex = maxBackupIndex; + return this; + } + + public Builder rotateOnBoot(boolean rotateOnBoot) { + this.rotateOnBoot = rotateOnBoot; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddSizeRotatingFileAuditLog build() { + if (path == null || path.isEmpty()) { + throw new IllegalArgumentException("Path must not be null and must have a minimum length of 1 character"); + } + + return new AddSizeRotatingFileAuditLog(this); + } + + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/audit/AddSyslogAuditLog.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/audit/AddSyslogAuditLog.java new file mode 100644 index 00000000..6f5df934 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/audit/AddSyslogAuditLog.java @@ -0,0 +1,131 @@ +package org.wildfly.extras.creaper.commands.elytron.audit; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddSyslogAuditLog implements OnlineCommand { + + private final String name; + private final String serverAddress; + private final Integer port; + private final TransportProtocolType transport; + private final AuditFormat format; + private final String hostName; + private final String sslContext; + private final boolean replaceExisting; + + private AddSyslogAuditLog(Builder builder) { + this.name = builder.name; + this.serverAddress = builder.serverAddress; + this.port = builder.port; + this.transport = builder.transport; + this.format = builder.format; + this.hostName = builder.hostName; + this.replaceExisting = builder.replaceExisting; + this.sslContext = builder.sslContext; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address syslogAuditAddress = Address.subsystem("elytron").and("syslog-audit-log", name); + if (replaceExisting) { + ops.removeIfExists(syslogAuditAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(syslogAuditAddress, Values.empty() + .and("server-address", serverAddress) + .and("port", port) + .and("host-name", hostName) + .andOptional("ssl-context", sslContext) + .andOptional("transport", transport == null ? null : transport.name()) + .andOptional("format", format == null ? null : format.name())); + } + + public static final class Builder { + + private final String name; + private String serverAddress; + private Integer port; + private TransportProtocolType transport; + private String hostName; + private AuditFormat format; + private String sslContext; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the syslog-audit-log must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the syslog-audit-log must not be empty value"); + } + this.name = name; + } + + public Builder serverAddress(String serverAddress) { + this.serverAddress = serverAddress; + return this; + } + + public Builder port(int port) { + this.port = port; + return this; + } + + public Builder transport(TransportProtocolType transport) { + this.transport = transport; + return this; + } + + public Builder hostName(String hostName) { + this.hostName = hostName; + return this; + } + + public Builder format(AuditFormat format) { + this.format = format; + return this; + } + + public Builder sslContext(String sslContext) { + this.sslContext = sslContext; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddSyslogAuditLog build() { + if (serverAddress == null || serverAddress.isEmpty()) { + throw new IllegalArgumentException("Server-address must not be null and must have a minimum length of 1 character"); + } + if (port == null) { + throw new IllegalArgumentException("Port must not be null"); + } + if (hostName == null || hostName.isEmpty()) { + throw new IllegalArgumentException("Host-name must not be null and must have a minimum length of 1 character"); + } + + return new AddSyslogAuditLog(this); + } + + } + + public static enum TransportProtocolType { + + UDP, TCP; + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/audit/AuditFormat.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/audit/AuditFormat.java new file mode 100644 index 00000000..18e40d61 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/audit/AuditFormat.java @@ -0,0 +1,7 @@ +package org.wildfly.extras.creaper.commands.elytron.audit; + +public enum AuditFormat { + + SIMPLE, JSON; + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/authenticationclient/AddAuthenticationConfiguration.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/authenticationclient/AddAuthenticationConfiguration.java new file mode 100644 index 00000000..7b90d01b --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/authenticationclient/AddAuthenticationConfiguration.java @@ -0,0 +1,232 @@ +package org.wildfly.extras.creaper.commands.elytron.authenticationclient; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.jboss.dmr.ModelNode; +import org.wildfly.extras.creaper.commands.elytron.CredentialRef; +import org.wildfly.extras.creaper.commands.elytron.Property; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddAuthenticationConfiguration implements OnlineCommand { + + private final String name; + private final List mechanismProperties; + private final CredentialRef credentialReference; + private final Boolean anonymous; + private final String authenticationName; + private final String authorizationName; + private final String extend; + private final String host; + private final Integer port; + private final String protocol; + private final String realm; + private final String securityDomain; + private final String saslMechanismSelector; + private final String kerberosSecurityFactory; + private final ForwardingMode forwardingMode; + private final boolean replaceExisting; + + private AddAuthenticationConfiguration(Builder builder) { + this.name = builder.name; + this.mechanismProperties = builder.mechanismProperties; + this.credentialReference = builder.credentialReference; + this.anonymous = builder.anonymous; + this.authenticationName = builder.authenticationName; + this.authorizationName = builder.authorizationName; + this.extend = builder.extend; + this.host = builder.host; + this.port = builder.port; + this.protocol = builder.protocol; + this.realm = builder.realm; + this.securityDomain = builder.securityDomain; + this.saslMechanismSelector = builder.saslMechanismSelector; + this.kerberosSecurityFactory = builder.kerberosSecurityFactory; + this.forwardingMode = builder.forwardingMode; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address realmAddress = Address.subsystem("elytron").and("authentication-configuration", name); + if (replaceExisting) { + ops.removeIfExists(realmAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ModelNode mechanismPropertiesNode = null; + if (mechanismProperties != null && !mechanismProperties.isEmpty()) { + mechanismPropertiesNode = new ModelNode(); + for (Property property : mechanismProperties) { + mechanismPropertiesNode.add(property.getKey(), property.getValue()); + } + mechanismPropertiesNode = mechanismPropertiesNode.asObject(); + } + + Values credentialReferenceValues = credentialReference != null ? credentialReference.toValues() : null; + String forwardingModeValue = forwardingMode == null ? null : forwardingMode.name().toLowerCase(); + + ops.add(realmAddress, Values.empty() + .andOptional("extends", extend) + .andOptional("anonymous", anonymous) + .andOptional("authentication-name", authenticationName) + .andOptional("authorization-name", authorizationName) + .andOptional("host", host) + .andOptional("protocol", protocol) + .andOptional("port", port) + .andOptional("realm", realm) + .andOptional("security-domain", securityDomain) + .andOptional("mechanism-properties", mechanismPropertiesNode) + .andOptional("sasl-mechanism-selector", saslMechanismSelector) + .andOptional("kerberos-security-factory", kerberosSecurityFactory) + .andOptional("forwarding-mode", forwardingModeValue) + .andObjectOptional("credential-reference", credentialReferenceValues)); + } + + public static final class Builder { + + private String name; + private List mechanismProperties = new ArrayList(); + private CredentialRef credentialReference; + private Boolean anonymous; + private String authenticationName; + private String authorizationName; + private String extend; + private String host; + private Integer port; + private String protocol; + private String realm; + private String securityDomain; + private String saslMechanismSelector; + private String kerberosSecurityFactory; + private ForwardingMode forwardingMode; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the authentication-configuration must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the authentication-configuration must not be empty value"); + } + this.name = name; + } + + public Builder addMechanismProperties(Property... mechanismProperties) { + if (mechanismProperties == null) { + throw new IllegalArgumentException("MechanismProperties added to authentication-configuration must not be null"); + } + Collections.addAll(this.mechanismProperties, mechanismProperties); + return this; + } + + public Builder credentialReference(CredentialRef credentialReference) { + this.credentialReference = credentialReference; + return this; + } + + public Builder anonymous(Boolean anonymous) { + this.anonymous = anonymous; + return this; + } + + public Builder authenticationName(String authenticationName) { + this.authenticationName = authenticationName; + return this; + } + + public Builder authorizationName(String authorizationName) { + this.authorizationName = authorizationName; + return this; + } + + public Builder extend(String extend) { + this.extend = extend; + return this; + } + + public Builder host(String host) { + this.host = host; + return this; + } + + public Builder port(Integer port) { + this.port = port; + return this; + } + + public Builder protocol(String protocol) { + this.protocol = protocol; + return this; + } + + public Builder realm(String realm) { + this.realm = realm; + return this; + } + + public Builder securityDomain(String securityDomain) { + this.securityDomain = securityDomain; + return this; + } + + public Builder saslMechanismSelector(String saslMechanismSelector) { + this.saslMechanismSelector = saslMechanismSelector; + return this; + } + + public Builder kerberosSecurityFactory(String kerberosSecurityFactory) { + this.kerberosSecurityFactory = kerberosSecurityFactory; + return this; + } + + public Builder forwardingMode(ForwardingMode forwardingMode) { + this.forwardingMode = forwardingMode; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddAuthenticationConfiguration build() { + + int authCounter = 0; + if (authenticationName != null) { + authCounter++; + } + if (anonymous != null) { + authCounter++; + } + if (securityDomain != null) { + authCounter++; + } + if (kerberosSecurityFactory != null) { + authCounter++; + } + if (authCounter > 1) { + throw new IllegalArgumentException("Only one of authentication-name, anonymous, security-domain and kerberos-security-factory can be set."); + } + return new AddAuthenticationConfiguration(this); + } + + } + + public static enum ForwardingMode { + + AUTHENTICATION, AUTHORIZATION + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/authenticationclient/AddAuthenticationContext.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/authenticationclient/AddAuthenticationContext.java new file mode 100644 index 00000000..1062e0d3 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/authenticationclient/AddAuthenticationContext.java @@ -0,0 +1,286 @@ +package org.wildfly.extras.creaper.commands.elytron.authenticationclient; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.jboss.dmr.ModelNode; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddAuthenticationContext implements OnlineCommand { + + private final String name; + private final String extend; + private final boolean replaceExisting; + private final List matchRules; + + private AddAuthenticationContext(Builder builder) { + this.name = builder.name; + this.extend = builder.extend; + this.replaceExisting = builder.replaceExisting; + this.matchRules = builder.matchRules; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address realmAddress = Address.subsystem("elytron").and("authentication-context", name); + if (replaceExisting) { + ops.removeIfExists(realmAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + List matchRulesNodeList = null; + if (matchRules != null && !matchRules.isEmpty()) { + matchRulesNodeList = new ArrayList(); + for (MatchRule matchRule : matchRules) { + ModelNode matchRuleNode = new ModelNode(); + addOptional(matchRuleNode, "match-abstract-type", matchRule.matchAbstractType); + addOptional(matchRuleNode, "match-abstract-type-authority", matchRule.matchAbstractTypeAuthority); + addOptional(matchRuleNode, "match-host", matchRule.matchHost); + addOptional(matchRuleNode, "match-local-security-domain", matchRule.matchLocalSecurityDomain); + addOptional(matchRuleNode, "match-no-user", matchRule.matchNoUser); + addOptional(matchRuleNode, "match-path", matchRule.matchPath); + addOptional(matchRuleNode, "match-port", matchRule.matchPort); + addOptional(matchRuleNode, "match-protocol", matchRule.matchProtocol); + addOptional(matchRuleNode, "match-urn", matchRule.matchUrn); + addOptional(matchRuleNode, "match-user", matchRule.matchUser); + addOptional(matchRuleNode, "authentication-configuration", matchRule.authenticationConfiguration); + addOptional(matchRuleNode, "ssl-context", matchRule.sslContext); + matchRulesNodeList.add(matchRuleNode.asObject()); + } + } + + ops.add(realmAddress, Values.empty() + .andOptional("extends", extend) + .andListOptional(ModelNode.class, "match-rules", matchRulesNodeList)); + } + + private void addOptional(ModelNode node, String name, String value) { + if (value != null && !value.isEmpty()) { + node.add(name, value); + } + } + + private void addOptional(ModelNode node, String name, Boolean value) { + if (value != null) { + node.add(name, value); + } + } + + private void addOptional(ModelNode node, String name, Integer value) { + if (value != null) { + node.add(name, value); + } + } + + public static final class Builder { + + private final String name; + private String extend; + private boolean replaceExisting; + private List matchRules = new ArrayList(); + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the authentication-context must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the authentication-context must not be empty value"); + } + this.name = name; + } + + public Builder extend(String extend) { + this.extend = extend; + return this; + } + + public Builder addMatchRules(MatchRule... matchRule) { + if (matchRule == null) { + throw new IllegalArgumentException("MatchRule added to authentication-context must not be null"); + } + Collections.addAll(this.matchRules, matchRule); + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddAuthenticationContext build() { + return new AddAuthenticationContext(this); + } + } + + public static final class MatchRule { + + private final String matchAbstractType; + private final String matchAbstractTypeAuthority; + private final String matchHost; + private final String matchLocalSecurityDomain; + private final Boolean matchNoUser; + private final String matchPath; + private final Integer matchPort; + private final String matchProtocol; + private final String matchUrn; + private final String matchUser; + private final String authenticationConfiguration; + private final String sslContext; + + private MatchRule(MatchRuleBuilder builder) { + this.matchAbstractType = builder.matchAbstractType; + this.matchAbstractTypeAuthority = builder.matchAbstractTypeAuthority; + this.matchHost = builder.matchHost; + this.matchLocalSecurityDomain = builder.matchLocalSecurityDomain; + this.matchNoUser = builder.matchNoUser; + this.matchPath = builder.matchPath; + this.matchPort = builder.matchPort; + this.matchProtocol = builder.matchProtocol; + this.matchUrn = builder.matchUrn; + this.matchUser = builder.matchUser; + this.authenticationConfiguration = builder.authenticationConfiguration; + this.sslContext = builder.sslContext; + } + + public String getMatchAbstractType() { + return matchAbstractType; + } + + public String getMatchAbstractTypeAuthority() { + return matchAbstractTypeAuthority; + } + + public String getMatchHost() { + return matchHost; + } + + public String getMatchLocalSecurityDomain() { + return matchLocalSecurityDomain; + } + + public Boolean getMatchNoUser() { + return matchNoUser; + } + + public String getMatchPath() { + return matchPath; + } + + public Integer getMatchPort() { + return matchPort; + } + + public String getMatchProtocol() { + return matchProtocol; + } + + public String getMatchUrn() { + return matchUrn; + } + + public String getMatchUser() { + return matchUser; + } + + public String getAuthenticationConfiguration() { + return authenticationConfiguration; + } + + public String getSslContext() { + return sslContext; + } + + } + + public static final class MatchRuleBuilder { + + private String matchAbstractType; + private String matchAbstractTypeAuthority; + private String matchHost; + private String matchLocalSecurityDomain; + private Boolean matchNoUser; + private String matchPath; + private Integer matchPort; + private String matchProtocol; + private String matchUrn; + private String matchUser; + private String authenticationConfiguration; + private String sslContext; + + public MatchRuleBuilder matchAbstractType(String matchAbstractType) { + this.matchAbstractType = matchAbstractType; + return this; + } + + public MatchRuleBuilder matchAbstractTypeAuthority(String matchAbstractTypeAuthority) { + this.matchAbstractTypeAuthority = matchAbstractTypeAuthority; + return this; + } + + public MatchRuleBuilder matchHost(String matchHost) { + this.matchHost = matchHost; + return this; + } + + public MatchRuleBuilder matchLocalSecurityDomain(String matchLocalSecurityDomain) { + this.matchLocalSecurityDomain = matchLocalSecurityDomain; + return this; + } + + public MatchRuleBuilder matchNoUser(Boolean matchNoUser) { + this.matchNoUser = matchNoUser; + return this; + } + + public MatchRuleBuilder matchPath(String matchPath) { + this.matchPath = matchPath; + return this; + } + + public MatchRuleBuilder matchPort(Integer matchPort) { + this.matchPort = matchPort; + return this; + } + + public MatchRuleBuilder matchProtocol(String matchProtocol) { + this.matchProtocol = matchProtocol; + return this; + } + + public MatchRuleBuilder matchUrn(String matchUrn) { + this.matchUrn = matchUrn; + return this; + } + + public MatchRuleBuilder matchUser(String matchUser) { + this.matchUser = matchUser; + return this; + } + + public MatchRuleBuilder authenticationConfiguration(String authenticationConfiguration) { + this.authenticationConfiguration = authenticationConfiguration; + return this; + } + + public MatchRuleBuilder sslContext(String sslContext) { + this.sslContext = sslContext; + return this; + } + + public MatchRule build() { + return new MatchRule(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/AddCredentialStore.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/AddCredentialStore.java new file mode 100644 index 00000000..29741281 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/AddCredentialStore.java @@ -0,0 +1,162 @@ +package org.wildfly.extras.creaper.commands.elytron.credentialstore; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.wildfly.extras.creaper.commands.elytron.CredentialRef; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddCredentialStore implements OnlineCommand { + + private final String name; + private final String type; + private final String providerName; + private final String providers; + private final String otherProviders; + private final String relativeTo; + private final CredentialRef credentialReference; + private final Boolean create; + private final Map implementationProperties; + private final String location; + private final Boolean modifiable; + private final boolean replaceExisting; + + private AddCredentialStore(Builder builder) { + this.name = builder.name; + this.type = builder.type; + this.providerName = builder.providerName; + this.providers = builder.providers; + this.otherProviders = builder.otherProviders; + this.relativeTo = builder.relativeTo; + this.credentialReference = builder.credentialReference; + this.create = builder.create; + this.implementationProperties = builder.implementationProperties; + this.location = builder.location; + this.modifiable = builder.modifiable; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address credentialStoreAddress = Address.subsystem("elytron").and("credential-store", name); + if (replaceExisting) { + ops.removeIfExists(credentialStoreAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(credentialStoreAddress, Values.empty() + .andObject("credential-reference", credentialReference.toValues()) + .andOptional("type", type) + .andOptional("provider-name", providerName) + .andOptional("providers", providers) + .andOptional("other-providers", otherProviders) + .andOptional("relative-to", relativeTo) + .andOptional("create", create) + .andOptional("location", location) + .andOptional("modifiable", modifiable) + .andObjectOptional("implementation-properties", Values.fromMap(implementationProperties))); + } + + public static final class Builder { + + private final String name; + private String type; + private String providerName; + private String providers; + private String otherProviders; + private String relativeTo; + private CredentialRef credentialReference; + private Boolean create; + private final Map implementationProperties = new LinkedHashMap(); + private String location; + private Boolean modifiable; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null || name.isEmpty()) { + throw new IllegalArgumentException("Name of the credential-store must be specified as non empty value"); + } + this.name = name; + } + + public Builder type(String type) { + this.type = type; + return this; + } + + public Builder providerName(String providerName) { + this.providerName = providerName; + return this; + } + + public Builder providers(String providers) { + this.providers = providers; + return this; + } + + public Builder otherProviders(String otherProviders) { + this.otherProviders = otherProviders; + return this; + } + + public Builder relativeTo(String relativeTo) { + this.relativeTo = relativeTo; + return this; + } + + public Builder credentialReference(CredentialRef credentialReference) { + this.credentialReference = credentialReference; + return this; + } + + public Builder create(boolean create) { + this.create = create; + return this; + } + + public Builder addImplementationProperties(String name, String value) { + if (name == null || name.isEmpty()) { + throw new IllegalArgumentException("Name of the implementation-property of the credential-store must not be null"); + } + if (value == null || value.isEmpty()) { + throw new IllegalArgumentException("Value of the implementation-property of the credential-store must not be null"); + } + implementationProperties.put(name, value); + return this; + } + + public Builder location(String location) { + this.location = location; + return this; + } + + public Builder modifiable(boolean modifiable) { + this.modifiable = modifiable; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddCredentialStore build() { + if (credentialReference == null) { + throw new IllegalArgumentException("Credential-reference of the credential-store must be specified"); + } + + return new AddCredentialStore(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/AddCredentialStoreAlias.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/AddCredentialStoreAlias.java new file mode 100644 index 00000000..5b23850a --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/AddCredentialStoreAlias.java @@ -0,0 +1,131 @@ +package org.wildfly.extras.creaper.commands.elytron.credentialstore; + +import java.io.IOException; +import java.util.List; + +import org.jboss.dmr.ModelNode; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.ModelNodeResult; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddCredentialStoreAlias implements OnlineCommand { + + private final String alias; + private final String credentialStore; + private final EntryType entryType; + private final String secretValue; + private final boolean replaceExisting; + + private AddCredentialStoreAlias(Builder builder) { + this.alias = builder.alias; + this.credentialStore = builder.credentialStore; + this.entryType = builder.entryType; + this.secretValue = builder.secretValue; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address credentialStoreAddress = Address.subsystem("elytron") + .and("credential-store", credentialStore); + if (replaceExisting) { + if (aliasExists(ops, credentialStoreAddress, alias)) { + ops.invoke("remove-alias", credentialStoreAddress, Values.empty().and("alias", alias)); + } + new Administration(ctx.client).reloadIfRequired(); + } + + ops.invoke("add-alias", credentialStoreAddress, Values.empty() + .and("secret-value", secretValue) + .and("alias", alias) + .andOptional("entry-type", entryType == null ? null : entryType.getEntryType())); + } + + private boolean aliasExists(Operations ops, Address credentialStore, String alias) throws IOException { + ModelNodeResult result = ops.invoke("read-aliases", credentialStore); + ModelNode modelNode = result != null ? result.value() : null; + if (result == null || !result.isSuccess() || modelNode.asList().isEmpty()) { + return false; + } + List aliasList = modelNode.asList(); + for (ModelNode aliasName : aliasList) { + if (alias.equals(aliasName.asString())) { + return true; + } + } + + return false; + } + + public static final class Builder { + + private final String alias; + private String credentialStore; + private EntryType entryType; + private String secretValue; + private boolean replaceExisting; + + public Builder(String alias) { + if (alias == null || alias.isEmpty()) { + throw new IllegalArgumentException("Name of the kerberos-security-factory must be specified as non empty value"); + } + this.alias = alias; + } + + public Builder credentialStore(String credentialStore) { + this.credentialStore = credentialStore; + return this; + } + + public Builder entryType(EntryType entryType) { + this.entryType = entryType; + return this; + } + + public Builder secretValue(String secretValue) { + this.secretValue = secretValue; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddCredentialStoreAlias build() { + if (credentialStore == null || credentialStore.isEmpty()) { + throw new IllegalArgumentException("credential-store must be specified as non empty value"); + } + if (secretValue == null || secretValue.isEmpty()) { + throw new IllegalArgumentException("secret-value must be specified as non empty value"); + } + + return new AddCredentialStoreAlias(this); + } + } + + public static enum EntryType { + + OTHER("Other"), PASSWORD_CREDENTIAL("org.wildfly.security.credential.PasswordCredential"); + + private final String entryTypeName; + + private EntryType(String entryTypeName) { + this.entryTypeName = entryTypeName; + } + + public String getEntryType() { + return entryTypeName; + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/RemoveCredentialStore.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/RemoveCredentialStore.java new file mode 100644 index 00000000..fb2ae971 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/RemoveCredentialStore.java @@ -0,0 +1,36 @@ +package org.wildfly.extras.creaper.commands.elytron.credentialstore; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; + +public final class RemoveCredentialStore implements OnlineCommand { + + private final String credentialStoreName; + + public RemoveCredentialStore(String credentialStoreName) { + if (credentialStoreName == null) { + throw new IllegalArgumentException("Name of the credential-store must be specified as non null value"); + } + if (credentialStoreName.isEmpty()) { + throw new IllegalArgumentException("Name of the credential-store must not be empty value"); + } + + this.credentialStoreName = credentialStoreName; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Address credentialStoreAddress = Address.subsystem("elytron").and("credential-store", credentialStoreName); + + Operations ops = new Operations(ctx.client); + ops.remove(credentialStoreAddress); + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/RemoveCredentialStoreAlias.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/RemoveCredentialStoreAlias.java new file mode 100644 index 00000000..1a75b29f --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/RemoveCredentialStoreAlias.java @@ -0,0 +1,47 @@ +package org.wildfly.extras.creaper.commands.elytron.credentialstore; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; + +public final class RemoveCredentialStoreAlias implements OnlineCommand { + + private final String credentialStoreName; + private final String credentialStoreAlias; + + public RemoveCredentialStoreAlias(String credentialStoreName, String credentialStoreAlias) { + if (credentialStoreName == null) { + throw new IllegalArgumentException("Name of the credential-store must be specified as non null value"); + } + if (credentialStoreName.isEmpty()) { + throw new IllegalArgumentException("Name of the credential-store must not be empty value"); + } + if (credentialStoreAlias == null) { + throw new IllegalArgumentException("Alias of the credential-store must be specified as non null value"); + } + if (credentialStoreAlias.isEmpty()) { + throw new IllegalArgumentException("Alias of the credential-store must not be empty value"); + } + + this.credentialStoreName = credentialStoreName; + this.credentialStoreAlias = credentialStoreAlias; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Address credentialStoreAddress = Address.subsystem("elytron") + .and("credential-store", credentialStoreName); + + Operations ops = new Operations(ctx.client); + ops.invoke("remove-alias", credentialStoreAddress, Values.empty() + .and("alias", credentialStoreAlias)); + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/credfactory/AddCustomCredentialSecurityFactory.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/credfactory/AddCustomCredentialSecurityFactory.java new file mode 100644 index 00000000..84b0dc07 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/credfactory/AddCustomCredentialSecurityFactory.java @@ -0,0 +1,54 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2016, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.wildfly.extras.creaper.commands.elytron.credfactory; + +import org.wildfly.extras.creaper.commands.elytron.AbstractAddCustom; +import org.wildfly.extras.creaper.commands.foundation.offline.xml.GroovyXmlTransform; + +public final class AddCustomCredentialSecurityFactory extends AbstractAddCustom { + + private AddCustomCredentialSecurityFactory(Builder builder) { + super(builder); + } + + @Override + protected String getCustomTypeName() { + return "custom-credential-security-factory"; + } + + @Override + protected GroovyXmlTransform.Builder getGroovyBuilder() { + return GroovyXmlTransform.of(AddCustomCredentialSecurityFactory.class); + } + + public static final class Builder extends AbstractAddCustom.Builder { + public Builder(String name) { + super(name); + } + + public AddCustomCredentialSecurityFactory build() { + checkClassNameAndModule(); + return new AddCustomCredentialSecurityFactory(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/credfactory/AddKerberosSecurityFactory.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/credfactory/AddKerberosSecurityFactory.java new file mode 100644 index 00000000..93d36519 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/credfactory/AddKerberosSecurityFactory.java @@ -0,0 +1,194 @@ +package org.wildfly.extras.creaper.commands.elytron.credfactory; + +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddKerberosSecurityFactory implements OnlineCommand { + + private final String name; + private final String principal; + private final List mechanismOIDs; + private final List mechanismNames; + private final String path; + private final String relativeTo; + private final Integer minimumRemainingLifetime; + private final Integer requestLifetime; + private final Boolean server; + private final Boolean debug; + private final Boolean obtainKerberosTicket; + private final Boolean wrapGssCredential; + private final Boolean required; + private final Map options; + private final boolean replaceExisting; + + private AddKerberosSecurityFactory(Builder builder) { + this.name = builder.name; + this.principal = builder.principal; + this.mechanismOIDs = builder.mechanismOIDs; + this.mechanismNames = builder.mechanismNames; + this.path = builder.path; + this.relativeTo = builder.relativeTo; + this.minimumRemainingLifetime = builder.minimumRemainingLifetime; + this.requestLifetime = builder.requestLifetime; + this.server = builder.server; + this.debug = builder.debug; + this.obtainKerberosTicket = builder.obtainKerberosTicket; + this.wrapGssCredential = builder.wrapGssCredential; + this.required = builder.required; + this.options = builder.options; + // Replace existing + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address kerberosSecurityFactoryAddress = Address.subsystem("elytron").and("kerberos-security-factory", name); + if (replaceExisting) { + ops.removeIfExists(kerberosSecurityFactoryAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(kerberosSecurityFactoryAddress, Values.empty() + .and("name", name) + .and("principal", principal) + .and("path", path) + .andListOptional(String.class, "mechanism-oids", mechanismOIDs) + .andListOptional(String.class, "mechanism-names", mechanismNames) + .andOptional("relative-to", relativeTo) + .andOptional("minimum-remaining-lifetime", minimumRemainingLifetime) + .andOptional("request-lifetime", requestLifetime) + .andOptional("server", server) + .andOptional("debug", debug) + .andOptional("obtain-kerberos-ticket", obtainKerberosTicket) + .andOptional("wrap-gss-credential", wrapGssCredential) + .andOptional("required", required) + .andObjectOptional("options", Values.fromMap(options))); + } + + public static final class Builder { + + private final String name; + private String principal; + private List mechanismOIDs; + private List mechanismNames; + private String path; + private String relativeTo; + private Integer minimumRemainingLifetime; + private Integer requestLifetime; + private Boolean server; + private Boolean debug; + private Boolean obtainKerberosTicket; + private Boolean wrapGssCredential; + private Boolean required; + private Map options = new LinkedHashMap(); + private boolean replaceExisting; + + public Builder(String name) { + if (name == null || name.isEmpty()) { + throw new IllegalArgumentException("Name of the kerberos-security-factory must be specified as non empty value"); + } + this.name = name; + } + + public Builder principal(String principal) { + this.principal = principal; + return this; + } + + public Builder mechanismOIDs(String... mechanismOIDs) { + if (mechanismOIDs != null && mechanismOIDs.length > 0) { + this.mechanismOIDs = Arrays.asList(mechanismOIDs); + } + return this; + } + + public Builder mechanismNames(String... mechanismNames) { + if (mechanismNames != null && mechanismNames.length > 0) { + this.mechanismNames = Arrays.asList(mechanismNames); + } + return this; + } + + public Builder path(String path) { + this.path = path; + return this; + } + + public Builder relativeTo(String relativeTo) { + this.relativeTo = relativeTo; + return this; + } + + public Builder minimumRemainingLifetime(Integer minimumRemainingLifetime) { + this.minimumRemainingLifetime = minimumRemainingLifetime; + return this; + } + + public Builder requestLifetime(Integer requestLifetime) { + this.requestLifetime = requestLifetime; + return this; + } + + public Builder server(Boolean server) { + this.server = server; + return this; + } + + public Builder debug(Boolean debug) { + this.debug = debug; + return this; + } + + public Builder obtainKerberosTicket(Boolean obtainKerberosTicket) { + this.obtainKerberosTicket = obtainKerberosTicket; + return this; + } + + public Builder wrapGssCredential(Boolean wrapGssCredential) { + this.wrapGssCredential = wrapGssCredential; + return this; + } + + public Builder required(Boolean required) { + this.required = required; + return this; + } + + public Builder addOption(String name, String value) { + options.put(name, value); + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddKerberosSecurityFactory build() { + if (principal == null || principal.isEmpty()) { + throw new IllegalArgumentException("Principal of the kerberos-security-factory must be specified as non empty value"); + } + if (path == null || path.isEmpty()) { + throw new IllegalArgumentException("Path of the kerberos-security-factory must be specified as non empty value"); + } + + return new AddKerberosSecurityFactory(this); + } + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/dircontext/AddDirContext.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/dircontext/AddDirContext.java new file mode 100644 index 00000000..2898f56e --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/dircontext/AddDirContext.java @@ -0,0 +1,208 @@ +package org.wildfly.extras.creaper.commands.elytron.dircontext; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.jboss.dmr.ModelNode; +import org.wildfly.extras.creaper.commands.elytron.CredentialRef; +import org.wildfly.extras.creaper.commands.elytron.Property; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddDirContext implements OnlineCommand { + + private final String name; + private final String url; + private final AuthenticationLevel authenticationLevel; + private final String principal; + private final Boolean enableConnectionPooling; + private final String sslContext; + private final ReferralMode referralMode; + private final String authenticationContext; + private final Integer connectionTimeout; + private final Integer readTimeout; + private final String module; + private final List properties; + private final CredentialRef credentialReference; + private final boolean replaceExisting; + + private AddDirContext(Builder builder) { + this.name = builder.name; + this.url = builder.url; + this.authenticationLevel = builder.authenticationLevel; + this.principal = builder.principal; + this.enableConnectionPooling = builder.enableConnectionPooling; + this.sslContext = builder.sslContext; + this.referralMode = builder.referralMode; + this.authenticationContext = builder.authenticationContext; + this.connectionTimeout = builder.connectionTimeout; + this.readTimeout = builder.readTimeout; + this.module = builder.module; + this.replaceExisting = builder.replaceExisting; + this.properties = builder.properties; + this.credentialReference = builder.credentialReference; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address dirContextAddress = Address.subsystem("elytron") + .and("dir-context", name); + if (replaceExisting) { + ops.removeIfExists(dirContextAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ModelNode propertiesNode = null; + if (properties != null && !properties.isEmpty()) { + propertiesNode = new ModelNode(); + for (Property property : properties) { + propertiesNode.add(property.getKey(), property.getValue()); + } + propertiesNode = propertiesNode.asObject(); + } + + String authenticationModeValue = authenticationLevel == null ? null : authenticationLevel.name(); + String referralModeValue = referralMode == null ? null : referralMode.name(); + Values credentialReferenceValues = credentialReference != null ? credentialReference.toValues() : null; + + ops.add(dirContextAddress, Values.empty() + .and("url", url) + .andOptional("authentication-level", authenticationModeValue) + .andOptional("principal", principal) + .andOptional("enable-connection-pooling", enableConnectionPooling) + .andOptional("ssl-context", sslContext) + .andOptional("referral-mode", referralModeValue) + .andOptional("authentication-context", authenticationContext) + .andOptional("connection-timeout", connectionTimeout) + .andOptional("read-timeout", readTimeout) + .andOptional("module", module) + .andOptional("properties", propertiesNode) + .andObjectOptional("credential-reference", credentialReferenceValues)); + } + + public static final class Builder { + + private final String name; + private String url; + private AuthenticationLevel authenticationLevel; + private String principal; + private Boolean enableConnectionPooling; + private String sslContext; + private ReferralMode referralMode; + private String authenticationContext; + private Integer connectionTimeout; + private Integer readTimeout; + private String module; + private List properties = new ArrayList(); + private CredentialRef credentialReference; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the dir-context must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the dir-context must not be empty value"); + } + this.name = name; + } + + public Builder url(String url) { + this.url = url; + return this; + } + + public Builder authenticationLevel(AuthenticationLevel authenticationLevel) { + this.authenticationLevel = authenticationLevel; + return this; + } + + public Builder principal(String principal) { + this.principal = principal; + return this; + } + + public Builder enableConnectionPooling(boolean enableConnectionPooling) { + this.enableConnectionPooling = enableConnectionPooling; + return this; + } + + public Builder sslContext(String sslContext) { + this.sslContext = sslContext; + return this; + } + + public Builder referralMode(ReferralMode referralMode) { + this.referralMode = referralMode; + return this; + } + + public Builder authenticationContext(String authenticationContext) { + this.authenticationContext = authenticationContext; + return this; + } + + public Builder connectionTimeout(Integer connectionTimeout) { + this.connectionTimeout = connectionTimeout; + return this; + } + + public Builder readTimeout(Integer readTimeout) { + this.readTimeout = readTimeout; + return this; + } + + public Builder module(String module) { + this.module = module; + return this; + } + + public Builder addProperties(Property... properties) { + if (properties == null) { + throw new IllegalArgumentException("Properties added to dir-context must not be null"); + } + Collections.addAll(this.properties, properties); + return this; + } + + public Builder credentialReference(CredentialRef credentialReference) { + this.credentialReference = credentialReference; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddDirContext build() { + if (url == null || url.isEmpty()) { + throw new IllegalArgumentException("url must not be null or empty"); + } + if (authenticationContext != null && credentialReference != null) { + throw new IllegalArgumentException("Only one of authentication-context and credential-reference can be set."); + } + return new AddDirContext(this); + } + } + + public static enum AuthenticationLevel { + + NONE, SIMPLE, STRONG + } + + public static enum ReferralMode { + + FOLLOW, IGNORE, THROW + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/domain/AddSecurityDomain.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/domain/AddSecurityDomain.java new file mode 100644 index 00000000..abba9b0d --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/domain/AddSecurityDomain.java @@ -0,0 +1,282 @@ +package org.wildfly.extras.creaper.commands.elytron.domain; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.jboss.dmr.ModelNode; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddSecurityDomain implements OnlineCommand { + + private final String name; + private final String defaultRealm; + private final String preRealmPrincipalTransformer; + private final String postRealmPrincipalTransformer; + private final String principalDecoder; + private final String realmMapper; + private final String roleMapper; + private final String permissionMapper; + private final List trustedSecurityDomains; + private final Boolean outflowAnonymous; + private final List outflowSecurityDomains; + private final String securityEventListener; + private final List realms; + private final boolean replaceExisting; + + private AddSecurityDomain(Builder builder) { + this.name = builder.name; + this.defaultRealm = builder.defaultRealm; + this.preRealmPrincipalTransformer = builder.preRealmPrincipalTransformer; + this.postRealmPrincipalTransformer = builder.postRealmPrincipalTransformer; + this.principalDecoder = builder.principalDecoder; + this.realmMapper = builder.realmMapper; + this.roleMapper = builder.roleMapper; + this.permissionMapper = builder.permissionMapper; + this.replaceExisting = builder.replaceExisting; + this.realms = builder.realms; + this.trustedSecurityDomains = builder.trustedSecurityDomains; + this.outflowAnonymous = builder.outflowAnonymous; + this.outflowSecurityDomains = builder.outflowSecurityDomains; + this.securityEventListener = builder.securityEventListener; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address securityDomainAddress = Address.subsystem("elytron").and("security-domain", name); + if (replaceExisting) { + ops.removeIfExists(securityDomainAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + List realmsModelNodeList = new ArrayList(); + for (Realm realm : realms) { + ModelNode configNode = new ModelNode(); + configNode.add("realm", realm.getName()); + if (realm.getPrincipalTransformer() != null && !realm.getPrincipalTransformer().isEmpty()) { + configNode.add("principal-transformer", realm.getPrincipalTransformer()); + } + if (realm.getRoleDecoder() != null && !realm.getRoleDecoder().isEmpty()) { + configNode.add("role-decoder", realm.getRoleDecoder()); + } + if (realm.getRoleMapper() != null && !realm.getRoleMapper().isEmpty()) { + configNode.add("role-mapper", realm.getRoleMapper()); + } + configNode = configNode.asObject(); + realmsModelNodeList.add(configNode); + } + + ops.add(securityDomainAddress, Values.empty() + .andOptional("default-realm", defaultRealm) + .andList(ModelNode.class, "realms", realmsModelNodeList) + .andOptional("pre-realm-principal-transformer", preRealmPrincipalTransformer) + .andOptional("post-realm-principal-transformer", postRealmPrincipalTransformer) + .andOptional("principal-decoder", principalDecoder) + .andOptional("realm-mapper", realmMapper) + .andOptional("role-mapper", roleMapper) + .andOptional("permission-mapper", permissionMapper) + .andListOptional(String.class, "trusted-security-domains", trustedSecurityDomains) + .andOptional("outflow-anonymous", outflowAnonymous) + .andOptional("security-event-listener", securityEventListener) + .andListOptional(String.class, "outflow-security-domains", outflowSecurityDomains)); + } + + public static final class Builder { + + private final String name; + private String defaultRealm; + private String preRealmPrincipalTransformer; + private String postRealmPrincipalTransformer; + private String principalDecoder; + private String realmMapper; + private String roleMapper; + private String permissionMapper; + private List trustedSecurityDomains; + private Boolean outflowAnonymous; + private List outflowSecurityDomains; + private String securityEventListener; + private List realms; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the security-domain must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the security-domain must not be empty value"); + } + this.name = name; + } + + public Builder defaultRealm(String defaultRealm) { + this.defaultRealm = defaultRealm; + return this; + } + + public Builder preRealmPrincipalTransformer(String preRealmPrincipalTransformer) { + this.preRealmPrincipalTransformer = preRealmPrincipalTransformer; + return this; + } + + public Builder postRealmPrincipalTransformer(String postRealmPrincipalTransformer) { + this.postRealmPrincipalTransformer = postRealmPrincipalTransformer; + return this; + } + + public Builder principalDecoder(String principalDecoder) { + this.principalDecoder = principalDecoder; + return this; + } + + public Builder realmMapper(String realmMapper) { + this.realmMapper = realmMapper; + return this; + } + + public Builder roleMapper(String roleMapper) { + this.roleMapper = roleMapper; + return this; + } + + public Builder permissionMapper(String permissionMapper) { + this.permissionMapper = permissionMapper; + return this; + } + + public Builder trustedSecurityDomains(String... trustedSecurityDomains) { + if (trustedSecurityDomains == null) { + throw new IllegalArgumentException("Trusted Security Domains added to security-domain must not be null"); + } + if (this.trustedSecurityDomains == null) { + this.trustedSecurityDomains = new ArrayList(); + } + Collections.addAll(this.trustedSecurityDomains, trustedSecurityDomains); + return this; + } + + public Builder outflowAnonymous(Boolean outflowAnonymous) { + this.outflowAnonymous = outflowAnonymous; + return this; + } + + public Builder outflowSecurityDomains(String... outflowSecurityDomains) { + if (outflowSecurityDomains == null) { + throw new IllegalArgumentException("Outflow Security Domains added to security-domain must not be null"); + } + if (this.outflowSecurityDomains == null) { + this.outflowSecurityDomains = new ArrayList(); + } + Collections.addAll(this.outflowSecurityDomains, outflowSecurityDomains); + return this; + } + + public Builder securityEventListener(String securityEventListener) { + this.securityEventListener = securityEventListener; + return this; + } + + public Builder realms(Realm... realms) { + if (realms == null) { + throw new IllegalArgumentException("Realms added to security-domain must not be null"); + } + if (this.realms == null) { + this.realms = new ArrayList(); + } + Collections.addAll(this.realms, realms); + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddSecurityDomain build() { + if (realms == null || realms.isEmpty()) { + throw new IllegalArgumentException("realms must not be null and must include at least one entry"); + } + return new AddSecurityDomain(this); + } + + } + + public static final class Realm { + + private final String name; + private final String principalTransformer; + private final String roleDecoder; + private final String roleMapper; + + private Realm(RealmBuilder builder) { + this.name = builder.name; + this.principalTransformer = builder.principalTransformer; + this.roleDecoder = builder.roleDecoder; + this.roleMapper = builder.roleMapper; + } + + public String getName() { + return name; + } + + public String getPrincipalTransformer() { + return principalTransformer; + } + + public String getRoleDecoder() { + return roleDecoder; + } + + public String getRoleMapper() { + return roleMapper; + } + + } + + public static final class RealmBuilder { + + private final String name; + private String principalTransformer; + private String roleDecoder; + private String roleMapper; + + public RealmBuilder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the realm in security-domain must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the realm in security-domain must not be empty value"); + } + this.name = name; + } + + public RealmBuilder principalTransformer(String principalTransformer) { + this.principalTransformer = principalTransformer; + return this; + } + + public RealmBuilder roleDecoder(String roleDecoder) { + this.roleDecoder = roleDecoder; + return this; + } + + public RealmBuilder roleMapper(String roleMapper) { + this.roleMapper = roleMapper; + return this; + } + + public Realm build() { + return new Realm(this); + } + + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/http/AddAggregateHttpServerMechanismFactory.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/http/AddAggregateHttpServerMechanismFactory.java new file mode 100644 index 00000000..81c39e79 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/http/AddAggregateHttpServerMechanismFactory.java @@ -0,0 +1,81 @@ +package org.wildfly.extras.creaper.commands.elytron.http; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddAggregateHttpServerMechanismFactory implements OnlineCommand { + + private final String name; + private final List httpServerMechanismFactories; + private final boolean replaceExisting; + + private AddAggregateHttpServerMechanismFactory(Builder builder) { + this.name = builder.name; + this.httpServerMechanismFactories = builder.httpServerMechanismFactories; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address factoryAddress = Address.subsystem("elytron") + .and("aggregate-http-server-mechanism-factory", name); + if (replaceExisting) { + ops.removeIfExists(factoryAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(factoryAddress, Values.empty() + .andList(String.class, "http-server-mechanism-factories", httpServerMechanismFactories)); + } + + public static final class Builder { + + private final String name; + private List httpServerMechanismFactories = new ArrayList(); + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the aggregate-http-server-mechanism-factory must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the aggregate-http-server-mechanism-factory must not be empty value"); + } + this.name = name; + } + + public Builder addHttpServerMechanismFactories(String... httpServerMechanismFactories) { + if (httpServerMechanismFactories == null) { + throw new IllegalArgumentException("http-server-mechanism-factories added to aggregate-http-server-mechanism-factory must not be null"); + } + Collections.addAll(this.httpServerMechanismFactories, httpServerMechanismFactories); + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddAggregateHttpServerMechanismFactory build() { + if (httpServerMechanismFactories == null || httpServerMechanismFactories.size() < 2) { + throw new IllegalArgumentException("http-server-mechanism-factory must not be null and must include at least two entries"); + } + return new AddAggregateHttpServerMechanismFactory(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/http/AddConfigurableHttpServerMechanismFactory.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/http/AddConfigurableHttpServerMechanismFactory.java new file mode 100644 index 00000000..bb1f0de5 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/http/AddConfigurableHttpServerMechanismFactory.java @@ -0,0 +1,173 @@ +package org.wildfly.extras.creaper.commands.elytron.http; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.jboss.dmr.ModelNode; +import org.wildfly.extras.creaper.commands.elytron.Property; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddConfigurableHttpServerMechanismFactory implements OnlineCommand { + + private final String name; + private final String httpServerMechanismFactory; + private final List filters; + private final List properties; + private final boolean replaceExisting; + + private AddConfigurableHttpServerMechanismFactory(Builder builder) { + this.name = builder.name; + this.httpServerMechanismFactory = builder.httpServerMechanismFactory; + this.filters = builder.filters; + this.properties = builder.properties; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address factoryAddress = Address.subsystem("elytron") + .and("configurable-http-server-mechanism-factory", name); + if (replaceExisting) { + ops.removeIfExists(factoryAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + List filterNodeList = null; + if (filters != null && !filters.isEmpty()) { + filterNodeList = new ArrayList(); + for (Filter filter : filters) { + ModelNode filterNode = new ModelNode(); + filterNode.add("pattern-filter", filter.getPatternFilter()); + if (filter.getEnabling() != null) { + filterNode.add("enabling", filter.getEnabling()); + } + filterNode = filterNode.asObject(); + filterNodeList.add(filterNode); + } + } + + ModelNode propertyNode = null; + if (properties != null && !properties.isEmpty()) { + propertyNode = new ModelNode(); + for (Property property : properties) { + propertyNode.add(property.getKey(), property.getValue()); + } + propertyNode = propertyNode.asObject(); + } + + ops.add(factoryAddress, Values.empty() + .and("http-server-mechanism-factory", httpServerMechanismFactory) + .andListOptional(ModelNode.class, "filters", filterNodeList) + .andOptional("properties", propertyNode)); + + } + + public static final class Builder { + + private final String name; + private String httpServerMechanismFactory; + private List filters = new ArrayList(); + private List properties = new ArrayList(); + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the configurable-http-server-mechanism-factory must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the configurable-http-server-mechanism-factory must not be empty value"); + } + this.name = name; + } + + public Builder httpServerMechanismFactory(String httpServerMechanismFactory) { + this.httpServerMechanismFactory = httpServerMechanismFactory; + return this; + } + + public Builder addFilters(Filter... filters) { + if (filters == null) { + throw new IllegalArgumentException("Filters added to configurable-http-server-mechanism-factory must not be null"); + } + Collections.addAll(this.filters, filters); + return this; + } + + public Builder addProperties(Property... properties) { + if (properties == null) { + throw new IllegalArgumentException("Properties added to configurable-http-server-mechanism-factory must not be null"); + } + Collections.addAll(this.properties, properties); + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddConfigurableHttpServerMechanismFactory build() { + if (httpServerMechanismFactory == null || httpServerMechanismFactory.isEmpty()) { + throw new IllegalArgumentException("http-server-mechanism-factory must not be null and must include at least one entry"); + } + return new AddConfigurableHttpServerMechanismFactory(this); + } + + } + + public static final class Filter { + + private final String patternFilter; + private final Boolean enabling; + + private Filter(FilterBuilder builder) { + this.patternFilter = builder.patternFilter; + this.enabling = builder.enabling; + } + + public String getPatternFilter() { + return patternFilter; + } + + public Boolean getEnabling() { + return enabling; + } + + } + + public static final class FilterBuilder { + + private String patternFilter; + private Boolean enabling; + + public FilterBuilder patternFilter(String patternFilter) { + this.patternFilter = patternFilter; + return this; + } + + public FilterBuilder enabling(Boolean enabling) { + this.enabling = enabling; + return this; + } + + public Filter build() { + if (patternFilter == null || patternFilter.isEmpty()) { + throw new IllegalArgumentException("pattern-filter must not be null or empty"); + } + return new Filter(this); + } + + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/http/AddHttpAuthenticationFactory.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/http/AddHttpAuthenticationFactory.java new file mode 100644 index 00000000..b83a7914 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/http/AddHttpAuthenticationFactory.java @@ -0,0 +1,157 @@ +package org.wildfly.extras.creaper.commands.elytron.http; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.jboss.dmr.ModelNode; +import org.wildfly.extras.creaper.commands.elytron.Mechanism; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddHttpAuthenticationFactory implements OnlineCommand { + + private final String name; + private final String securityDomain; + private final String httpServerMechanismFactory; + private final List mechanismConfigurations; + private final boolean replaceExisting; + + private AddHttpAuthenticationFactory(Builder builder) { + this.name = builder.name; + this.securityDomain = builder.securityDomain; + this.httpServerMechanismFactory = builder.httpServerMechanismFactory; + this.mechanismConfigurations = builder.mechanismConfigurations; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address factoryAddress = Address.subsystem("elytron") + .and("http-authentication-factory", name); + if (replaceExisting) { + ops.removeIfExists(factoryAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + List mechanismConfigurationsNodeList = null; + if (mechanismConfigurations != null && !mechanismConfigurations.isEmpty()) { + mechanismConfigurationsNodeList = new ArrayList(); + for (Mechanism mechanismConfiguration : mechanismConfigurations) { + ModelNode mechanismNode = new ModelNode(); + addOptionalToModelNode(mechanismNode, "mechanism-name", mechanismConfiguration.getMechanismName()); + addOptionalToModelNode(mechanismNode, "host-name", mechanismConfiguration.getHostName()); + addOptionalToModelNode(mechanismNode, "protocol", mechanismConfiguration.getProtocol()); + addOptionalToModelNode(mechanismNode, "pre-realm-principal-transformer", + mechanismConfiguration.getPreRealmPrincipalTransformer()); + addOptionalToModelNode(mechanismNode, "post-realm-principal-transformer", + mechanismConfiguration.getPostRealmPrincipalTransformer()); + addOptionalToModelNode(mechanismNode, "final-principal-transformer", + mechanismConfiguration.getFinalPrincipalTransformer()); + addOptionalToModelNode(mechanismNode, "realm-mapper", mechanismConfiguration.getRealmMapper()); + addOptionalToModelNode(mechanismNode, "credential-security-factory", + mechanismConfiguration.getCredentialSecurityFactory()); + + List mechanismRealmConfigurationsNodeList = null; + if (mechanismConfiguration.getMechanismRealmConfigurations() != null + && !mechanismConfiguration.getMechanismRealmConfigurations().isEmpty()) { + + mechanismRealmConfigurationsNodeList = new ArrayList(); + for (Mechanism.MechanismRealm mechanismRealm + : mechanismConfiguration.getMechanismRealmConfigurations()) { + ModelNode mechanismRealmNode = new ModelNode(); + mechanismRealmNode.add("realm-name", mechanismRealm.getRealmName()); + addOptionalToModelNode(mechanismRealmNode, "pre-realm-principal-transformer", + mechanismRealm.getPreRealmPrincipalTransformer()); + addOptionalToModelNode(mechanismRealmNode, "post-realm-principal-transformer", + mechanismRealm.getPostRealmPrincipalTransformer()); + addOptionalToModelNode(mechanismRealmNode, "final-principal-transformer", + mechanismRealm.getFinalPrincipalTransformer()); + addOptionalToModelNode(mechanismRealmNode, "realm-mapper", mechanismRealm.getRealmMapper()); + mechanismRealmNode = mechanismRealmNode.asObject(); + mechanismRealmConfigurationsNodeList.add(mechanismRealmNode); + } + ModelNode mechanismRealmConfigurations = new ModelNode(); + mechanismRealmConfigurations.set(mechanismRealmConfigurationsNodeList); + mechanismNode.add("mechanism-realm-configurations", mechanismRealmConfigurations); + } + + mechanismNode = mechanismNode.asObject(); + mechanismConfigurationsNodeList.add(mechanismNode); + } + } + + ops.add(factoryAddress, Values.empty() + .and("security-domain", securityDomain) + .and("http-server-mechanism-factory", httpServerMechanismFactory) + .andListOptional(ModelNode.class, "mechanism-configurations", mechanismConfigurationsNodeList)); + + } + + private void addOptionalToModelNode(ModelNode node, String name, String value) { + if (value != null && !value.isEmpty()) { + node.add(name, value); + } + } + + public static final class Builder { + + private final String name; + private String securityDomain; + private String httpServerMechanismFactory; + private List mechanismConfigurations = new ArrayList(); + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the http-authentication-factory must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the http-authentication-factory must not be empty value"); + } + this.name = name; + } + + public Builder securityDomain(String securityDomain) { + this.securityDomain = securityDomain; + return this; + } + + public Builder httpServerMechanismFactory(String httpServerMechanismFactory) { + this.httpServerMechanismFactory = httpServerMechanismFactory; + return this; + } + + public Builder addMechanismConfigurations(Mechanism... mechanismConfigurations) { + if (mechanismConfigurations == null) { + throw new IllegalArgumentException("Mechanism added to mechanism-configuration must not be null"); + } + Collections.addAll(this.mechanismConfigurations, mechanismConfigurations); + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddHttpAuthenticationFactory build() { + if (securityDomain == null || securityDomain.isEmpty()) { + throw new IllegalArgumentException("security-domain must not be null and must have a minimum length of 1 characters"); + } + if (httpServerMechanismFactory == null || httpServerMechanismFactory.isEmpty()) { + throw new IllegalArgumentException("http-server-mechanism-factory must not be null and must have a minimum length of 1 characters"); + } + return new AddHttpAuthenticationFactory(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/http/AddProviderHttpServerMechanismFactory.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/http/AddProviderHttpServerMechanismFactory.java new file mode 100644 index 00000000..72f34a44 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/http/AddProviderHttpServerMechanismFactory.java @@ -0,0 +1,72 @@ +package org.wildfly.extras.creaper.commands.elytron.http; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddProviderHttpServerMechanismFactory implements OnlineCommand { + + private final String name; + private final String providers; + private final boolean replaceExisting; + + private AddProviderHttpServerMechanismFactory(Builder builder) { + this.name = builder.name; + this.providers = builder.providers; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address factoryAddress = Address.subsystem("elytron") + .and("provider-http-server-mechanism-factory", name); + if (replaceExisting) { + ops.removeIfExists(factoryAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(factoryAddress, Values.empty() + .andOptional("providers", providers)); + } + + public static final class Builder { + + private final String name; + private String providers; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the provider-http-server-mechanism-factory must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the provider-http-server-mechanism-factory must not be empty value"); + } + this.name = name; + } + + public Builder providers(String providers) { + this.providers = providers; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddProviderHttpServerMechanismFactory build() { + return new AddProviderHttpServerMechanismFactory(this); + } + + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/http/AddServiceLoaderHttpServerMechanismFactory.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/http/AddServiceLoaderHttpServerMechanismFactory.java new file mode 100644 index 00000000..84d372b1 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/http/AddServiceLoaderHttpServerMechanismFactory.java @@ -0,0 +1,73 @@ +package org.wildfly.extras.creaper.commands.elytron.http; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddServiceLoaderHttpServerMechanismFactory implements OnlineCommand { + + private final String name; + private final String module; + private final boolean replaceExisting; + + private AddServiceLoaderHttpServerMechanismFactory(Builder builder) { + this.name = builder.name; + this.module = builder.module; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address factoryAddress = Address.subsystem("elytron") + .and("service-loader-http-server-mechanism-factory", name); + if (replaceExisting) { + ops.removeIfExists(factoryAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(factoryAddress, Values.empty() + .andOptional("module", module)); + } + + public static final class Builder { + + private final String name; + private String module; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the service-loader-http-server-mechanism-factory must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the service-loader-http-server-mechanism-factory must not be empty value"); + } + this.name = name; + } + + public Builder module(String module) { + this.module = module; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddServiceLoaderHttpServerMechanismFactory build() { + return new AddServiceLoaderHttpServerMechanismFactory(this); + } + + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AbstractAddPrincipalDecoder.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AbstractAddPrincipalDecoder.java new file mode 100644 index 00000000..32925e3c --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AbstractAddPrincipalDecoder.java @@ -0,0 +1,66 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.wildfly.extras.creaper.core.online.OnlineCommand; + +abstract class AbstractAddPrincipalDecoder implements OnlineCommand { + + protected final String name; + protected final List principalDecoders; + protected final boolean replaceExisting; + + protected AbstractAddPrincipalDecoder(Builder builder) { + this.name = builder.name; + this.principalDecoders = builder.principalDecoders; + this.replaceExisting = builder.replaceExisting; + } + + abstract static class Builder { + + protected final String name; + protected final List principalDecoders = new ArrayList(); + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the aggregate-principal-decoder must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the aggregate-principal-decoder must not be empty value"); + } + this.name = name; + } + + /** + * Sets principal decoders that should be aggregated/concatenated. At least 2 principal decoders + * must be defined. It is possible to use following types as a principal decoder: + *
    + *
  • customPrincipalDecoderType
  • + *
  • aggregate-principal-decoder
  • + *
  • concatenating-principal-decoder
  • + *
  • constant-principal-decoder
  • + *
  • x500-attribute-principal-decoder
  • + *
+ * + * @param principalDecoders previously defined principal-decoder + * @return builder + */ + public final THIS principalDecoders(String... principalDecoders) { + if (principalDecoders == null) { + throw new IllegalArgumentException("Principal decoder added to aggregate-principal-decoder must not be null"); + } + Collections.addAll(this.principalDecoders, principalDecoders); + return (THIS) this; + } + + public final THIS replaceExisting() { + this.replaceExisting = true; + return (THIS) this; + } + + public abstract AbstractAddPrincipalDecoder build(); + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AbstractAddPrincipalTransformer.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AbstractAddPrincipalTransformer.java new file mode 100644 index 00000000..45edc20d --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AbstractAddPrincipalTransformer.java @@ -0,0 +1,65 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.wildfly.extras.creaper.core.online.OnlineCommand; + +abstract class AbstractAddPrincipalTransformer implements OnlineCommand { + protected final String name; + protected final List principalTransformers; + protected final boolean replaceExisting; + + protected AbstractAddPrincipalTransformer(Builder builder) { + this.name = builder.name; + this.principalTransformers = builder.principalTransformers; + this.replaceExisting = builder.replaceExisting; + } + + abstract static class Builder { + + protected final String name; + protected final List principalTransformers = new ArrayList(); + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the name-decoder must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the name-decoder must not be empty value"); + } + this.name = name; + } + + /** + * Sets principal transformers that should be aggregated/chained. At least 2 principal transformers must be + * defined. It is possible to use following types as a principal transformer: + *
    + *
  • aggregate-principal-transformer
  • + *
  • chained-principal-transformer
  • + *
  • constant-principal-transformer
  • + *
  • custom-principal-transformer
  • + *
  • regex-principal-transformer
  • + *
  • regex-validating-principal-transformer
  • + *
+ * + * @param principalTransformers previously defined principal-decoder + * @return builder + */ + public final THIS principalTransformers(String... principalTransformers) { + if (principalTransformers == null) { + throw new IllegalArgumentException("Added principal transformer must not be null"); + } + Collections.addAll(this.principalTransformers, principalTransformers); + return (THIS) this; + } + + public final THIS replaceExisting() { + this.replaceExisting = true; + return (THIS) this; + } + + public abstract AbstractAddPrincipalTransformer build(); + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAddPrefixRoleMapper.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAddPrefixRoleMapper.java new file mode 100644 index 00000000..3c02f50d --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAddPrefixRoleMapper.java @@ -0,0 +1,74 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddAddPrefixRoleMapper implements OnlineCommand { + + private final String name; + private final String prefix; + private final boolean replaceExisting; + + private AddAddPrefixRoleMapper(Builder builder) { + this.name = builder.name; + this.prefix = builder.prefix; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address mapperAddress = Address.subsystem("elytron").and("add-prefix-role-mapper", name); + if (replaceExisting) { + ops.removeIfExists(mapperAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(mapperAddress, Values.empty() + .and("prefix", prefix)); + } + + public static final class Builder { + + private final String name; + private String prefix; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the add-prefix-role-mapper must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the add-prefix-role-mapper must not be empty value"); + } + + this.name = name; + } + + public Builder prefix(String prefix) { + this.prefix = prefix; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddAddPrefixRoleMapper build() { + if (prefix == null || prefix.isEmpty()) { + throw new IllegalArgumentException("prefix must not be null or empty string"); + } + return new AddAddPrefixRoleMapper(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAddSuffixRoleMapper.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAddSuffixRoleMapper.java new file mode 100644 index 00000000..b6e3f6d6 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAddSuffixRoleMapper.java @@ -0,0 +1,74 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddAddSuffixRoleMapper implements OnlineCommand { + + private final String name; + private final String suffix; + private final boolean replaceExisting; + + private AddAddSuffixRoleMapper(Builder builder) { + this.name = builder.name; + this.suffix = builder.suffix; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address mapperAddress = Address.subsystem("elytron").and("add-suffix-role-mapper", name); + if (replaceExisting) { + ops.removeIfExists(mapperAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(mapperAddress, Values.empty() + .and("suffix", suffix)); + } + + public static final class Builder { + + private final String name; + private String suffix; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the add-suffix-role-mapper must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the add-suffix-role-mapper must not be empty value"); + } + + this.name = name; + } + + public Builder suffix(String suffix) { + this.suffix = suffix; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddAddSuffixRoleMapper build() { + if (suffix == null || suffix.isEmpty()) { + throw new IllegalArgumentException("suffix must not be null or empty string"); + } + return new AddAddSuffixRoleMapper(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAggregatePrincipalDecoder.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAggregatePrincipalDecoder.java new file mode 100644 index 00000000..489086b2 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAggregatePrincipalDecoder.java @@ -0,0 +1,50 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddAggregatePrincipalDecoder extends AbstractAddPrincipalDecoder { + + private AddAggregatePrincipalDecoder(Builder builder) { + super(builder); + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address constantPrincipalDecoderAddress = Address.subsystem("elytron") + .and("aggregate-principal-decoder", name); + if (replaceExisting) { + ops.removeIfExists(constantPrincipalDecoderAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(constantPrincipalDecoderAddress, Values.empty() + .andList(String.class, "principal-decoders", principalDecoders)); + } + + public static final class Builder extends AbstractAddPrincipalDecoder.Builder { + + public Builder(String name) { + super(name); + } + + @Override + public AddAggregatePrincipalDecoder build() { + if (principalDecoders.size() < 2) { + throw new IllegalArgumentException("There must be at least two principal-decoders"); + } + return new AddAggregatePrincipalDecoder(this); + } + + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAggregatePrincipalTransformer.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAggregatePrincipalTransformer.java new file mode 100644 index 00000000..6f2a69e1 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAggregatePrincipalTransformer.java @@ -0,0 +1,49 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public class AddAggregatePrincipalTransformer extends AbstractAddPrincipalTransformer { + + private AddAggregatePrincipalTransformer(Builder builder) { + super(builder); + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address aggregatePrincipalTransformerAddress = Address.subsystem("elytron") + .and("aggregate-principal-transformer", name); + if (replaceExisting) { + ops.removeIfExists(aggregatePrincipalTransformerAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(aggregatePrincipalTransformerAddress, Values.empty() + .andList(String.class, "principal-transformers", principalTransformers)); + } + + public static final class Builder extends AbstractAddPrincipalTransformer.Builder { + + public Builder(String name) { + super(name); + } + + @Override + public AddAggregatePrincipalTransformer build() { + if (principalTransformers.size() < 2) { + throw new IllegalArgumentException("There must be at least two principal-transformers"); + } + return new AddAggregatePrincipalTransformer(this); + } + + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAggregateRoleMapper.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAggregateRoleMapper.java new file mode 100644 index 00000000..2d703e8f --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAggregateRoleMapper.java @@ -0,0 +1,81 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.wildfly.extras.creaper.core.ServerVersion; + +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddAggregateRoleMapper implements OnlineCommand { + + private final String name; + private final List roleMapperNameList; + private final boolean replaceExisting; + + private AddAggregateRoleMapper(Builder builder) { + this.name = builder.name; + this.roleMapperNameList = builder.roleMapperNameList; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address mapperAddress = Address.subsystem("elytron").and("aggregate-role-mapper", name); + if (replaceExisting) { + ops.removeIfExists(mapperAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(mapperAddress, Values.empty() + .andList(String.class, "role-mappers", roleMapperNameList)); + } + + public static final class Builder { + + private final String name; + private List roleMapperNameList = new ArrayList(); + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the add-aggregate-role-mapper must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the aggregate-role-mapper must not be empty value"); + } + + this.name = name; + } + + public Builder addRoleMappers(String... roleMappers) { + if (roleMappers == null) { + throw new IllegalArgumentException("Roles added to aggregate-role-mapper must not be null"); + } + Collections.addAll(this.roleMapperNameList, roleMappers); + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddAggregateRoleMapper build() { + if (roleMapperNameList == null || roleMapperNameList.isEmpty()) { + throw new IllegalArgumentException("role-mapper must not be null and must include at least one entry"); + } + return new AddAggregateRoleMapper(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddChainedPrincipalTransformer.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddChainedPrincipalTransformer.java new file mode 100644 index 00000000..8da5a0cf --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddChainedPrincipalTransformer.java @@ -0,0 +1,49 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public class AddChainedPrincipalTransformer extends AbstractAddPrincipalTransformer { + + private AddChainedPrincipalTransformer(Builder builder) { + super(builder); + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address aggregatePrincipalTransformerAddress = Address.subsystem("elytron") + .and("chained-principal-transformer", name); + if (replaceExisting) { + ops.removeIfExists(aggregatePrincipalTransformerAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(aggregatePrincipalTransformerAddress, Values.empty() + .andList(String.class, "principal-transformers", principalTransformers)); + } + + public static final class Builder extends AbstractAddPrincipalTransformer.Builder { + + public Builder(String name) { + super(name); + } + + @Override + public AddChainedPrincipalTransformer build() { + if (principalTransformers.size() < 2) { + throw new IllegalArgumentException("There must be at least two principal-transformers"); + } + return new AddChainedPrincipalTransformer(this); + } + + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConcatenatingPrincipalDecoder.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConcatenatingPrincipalDecoder.java new file mode 100644 index 00000000..e1ec2d81 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConcatenatingPrincipalDecoder.java @@ -0,0 +1,63 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddConcatenatingPrincipalDecoder extends AbstractAddPrincipalDecoder { + + private final String joiner; + + private AddConcatenatingPrincipalDecoder(Builder builder) { + super(builder); + this.joiner = builder.joiner; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address constantPrincipalDecoderAddress = Address.subsystem("elytron") + .and("concatenating-principal-decoder", name); + if (replaceExisting) { + ops.removeIfExists(constantPrincipalDecoderAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(constantPrincipalDecoderAddress, Values.empty() + .andList(String.class, "principal-decoders", principalDecoders) + .andOptional("joiner", joiner)); + } + + public static final class Builder extends AbstractAddPrincipalDecoder.Builder { + + private String joiner; + + public Builder(String name) { + super(name); + } + + public Builder joiner(String joiner) { + if (joiner == null || joiner.isEmpty()) { + throw new IllegalArgumentException("Joiner must not be null and must have a minimum length of 1 character"); + } + this.joiner = joiner; + return this; + } + + @Override + public AddConcatenatingPrincipalDecoder build() { + if (principalDecoders.size() < 2) { + throw new IllegalArgumentException("There must be at least two principal-decoders"); + } + return new AddConcatenatingPrincipalDecoder(this); + } + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantPermissionMapper.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantPermissionMapper.java new file mode 100644 index 00000000..b225cf1f --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantPermissionMapper.java @@ -0,0 +1,166 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.jboss.dmr.ModelNode; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddConstantPermissionMapper implements OnlineCommand { + + private final String name; + private final List permissions; + private final boolean replaceExisting; + + private AddConstantPermissionMapper(Builder builder) { + this.name = builder.name; + this.permissions = builder.permissions; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address mapperAddress = Address.subsystem("elytron").and("constant-permission-mapper", name); + if (replaceExisting) { + ops.removeIfExists(mapperAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + List mechanismConfigurationsNodeList = null; + if (permissions != null && !permissions.isEmpty()) { + mechanismConfigurationsNodeList = new ArrayList(); + for (Permission permission : permissions) { + ModelNode node = new ModelNode(); + node.add("class-name", permission.getClassName()); + addOptionalToModelNode(node, "module", permission.getModule()); + addOptionalToModelNode(node, "target-name", permission.getTargetName()); + addOptionalToModelNode(node, "action", permission.getAction()); + node = node.asObject(); + mechanismConfigurationsNodeList.add(node); + } + } + + ops.add(mapperAddress, Values.empty() + .andListOptional(ModelNode.class, "permissions", mechanismConfigurationsNodeList)); + } + + private void addOptionalToModelNode(ModelNode node, String name, String value) { + if (value != null && !value.isEmpty()) { + node.add(name, value); + } + } + + public static final class Builder { + + private final String name; + private List permissions = new ArrayList(); + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the constant-permission-mapper must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the constant-permission-mapper must not be empty value"); + } + this.name = name; + } + + public Builder addPermissions(Permission... permissions) { + if (permissions == null) { + throw new IllegalArgumentException("Permissions added to permission-mapping of constant-permission-mapper must not be null"); + } + Collections.addAll(this.permissions, permissions); + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddConstantPermissionMapper build() { + return new AddConstantPermissionMapper(this); + } + } + + public static final class Permission { + + private final String className; + private final String module; + private final String targetName; + private final String action; + + private Permission(PermissionBuilder builder) { + this.className = builder.className; + this.module = builder.module; + this.targetName = builder.targetName; + this.action = builder.action; + } + + public String getClassName() { + return className; + } + + public String getModule() { + return module; + } + + public String getTargetName() { + return targetName; + } + + public String getAction() { + return action; + } + + } + + public static final class PermissionBuilder { + + private String className; + private String module; + private String targetName; + private String action; + + public PermissionBuilder className(String className) { + this.className = className; + return this; + } + + public PermissionBuilder module(String module) { + this.module = module; + return this; + } + + public PermissionBuilder targetName(String targetName) { + this.targetName = targetName; + return this; + } + + public PermissionBuilder action(String action) { + this.action = action; + return this; + } + + public Permission build() { + if (className == null || className.isEmpty()) { + throw new IllegalArgumentException("class-name must not be null and must have a minimum length of 1 characters"); + } + return new Permission(this); + } + } + + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantPrincipalDecoder.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantPrincipalDecoder.java new file mode 100644 index 00000000..ee6687a5 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantPrincipalDecoder.java @@ -0,0 +1,74 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddConstantPrincipalDecoder implements OnlineCommand { + + private final String name; + private final String constant; + private final boolean replaceExisting; + + private AddConstantPrincipalDecoder(Builder builder) { + this.name = builder.name; + this.constant = builder.constant; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address constantPrincipalDecoderAddress = Address.subsystem("elytron").and("constant-principal-decoder", name); + if (replaceExisting) { + ops.removeIfExists(constantPrincipalDecoderAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(constantPrincipalDecoderAddress, Values.empty() + .and("constant", constant)); + } + + public static final class Builder { + + private final String name; + private String constant; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the constant-principal-decoder must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the constant-principal-decoder must not be empty value"); + } + this.name = name; + } + + public Builder constant(String constant) { + this.constant = constant; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddConstantPrincipalDecoder build() { + if (constant == null || constant.isEmpty()) { + throw new IllegalArgumentException("Constant must not be null and must have a minimum length of 1 character"); + } + return new AddConstantPrincipalDecoder(this); + } + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantPrincipalTransformer.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantPrincipalTransformer.java new file mode 100644 index 00000000..d85c85e9 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantPrincipalTransformer.java @@ -0,0 +1,75 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddConstantPrincipalTransformer implements OnlineCommand { + + private final String name; + private final String constant; + private final boolean replaceExisting; + + private AddConstantPrincipalTransformer(Builder builder) { + this.name = builder.name; + this.constant = builder.constant; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address constantPrincipalTransformerAddress = Address.subsystem("elytron") + .and("constant-principal-transformer", name); + if (replaceExisting) { + ops.removeIfExists(constantPrincipalTransformerAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(constantPrincipalTransformerAddress, Values.empty() + .and("constant", constant)); + } + + public static final class Builder { + + private final String name; + private String constant; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the constant-principal-transformer must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the constant-principal-transformer must not be empty value"); + } + this.name = name; + } + + public Builder constant(String constant) { + this.constant = constant; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddConstantPrincipalTransformer build() { + if (constant == null || constant.isEmpty()) { + throw new IllegalArgumentException("Constant must not be null and must have a minimum length of 1 character"); + } + return new AddConstantPrincipalTransformer(this); + } + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantRealmMapper.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantRealmMapper.java new file mode 100644 index 00000000..b4d1ed73 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantRealmMapper.java @@ -0,0 +1,74 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddConstantRealmMapper implements OnlineCommand { + + private final String name; + private final String realmName; + private final boolean replaceExisting; + + private AddConstantRealmMapper(Builder builder) { + this.name = builder.name; + this.realmName = builder.realmName; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address constantRealmMapperAddress = Address.subsystem("elytron").and("constant-realm-mapper", name); + if (replaceExisting) { + ops.removeIfExists(constantRealmMapperAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(constantRealmMapperAddress, Values.empty() + .and("realm-name", realmName)); + } + + public static final class Builder { + + private final String name; + private String realmName; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the constant-realm-mapper must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the constant-realm-mapper must not be empty value"); + } + this.name = name; + } + + public Builder realmName(String realmName) { + this.realmName = realmName; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddConstantRealmMapper build() { + if (realmName == null || realmName.isEmpty()) { + throw new IllegalArgumentException("Realm-name must not be null and must have a minimum length of 1 character"); + } + return new AddConstantRealmMapper(this); + } + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantRoleMapper.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantRoleMapper.java new file mode 100644 index 00000000..36c0e52a --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantRoleMapper.java @@ -0,0 +1,80 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.wildfly.extras.creaper.core.ServerVersion; + +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddConstantRoleMapper implements OnlineCommand { + + private final String name; + private final List roles; + private final boolean replaceExisting; + + private AddConstantRoleMapper(Builder builder) { + this.name = builder.name; + this.roles = builder.roles; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address mapperAddress = Address.subsystem("elytron").and("constant-role-mapper", name); + if (replaceExisting) { + ops.removeIfExists(mapperAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(mapperAddress, Values.empty() + .andList(String.class, "roles", roles)); + } + + public static final class Builder { + + private final String name; + private final List roles = new ArrayList(); + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the constant-role-mapper must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the constant-role-mapper must not be empty value"); + } + this.name = name; + } + + public Builder addRoles(String... roles) { + if (roles == null) { + throw new IllegalArgumentException("Roles added to constant-role-mapper must not be null"); + } + Collections.addAll(this.roles, roles); + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddConstantRoleMapper build() { + if (roles == null || roles.isEmpty()) { + throw new IllegalArgumentException("roles must not be null and must include at least one entry"); + } + return new AddConstantRoleMapper(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPermissionMapper.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPermissionMapper.java new file mode 100644 index 00000000..a85ac40b --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPermissionMapper.java @@ -0,0 +1,54 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2016, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.wildfly.extras.creaper.commands.elytron.AbstractAddCustom; +import org.wildfly.extras.creaper.commands.foundation.offline.xml.GroovyXmlTransform; + +public final class AddCustomPermissionMapper extends AbstractAddCustom { + + private AddCustomPermissionMapper(Builder builder) { + super(builder); + } + + @Override + protected String getCustomTypeName() { + return "custom-permission-mapper"; + } + + @Override + protected GroovyXmlTransform.Builder getGroovyBuilder() { + return GroovyXmlTransform.of(AddCustomPermissionMapper.class); + } + + public static final class Builder extends AbstractAddCustom.Builder { + public Builder(String name) { + super(name); + } + + public AddCustomPermissionMapper build() { + checkClassNameAndModule(); + return new AddCustomPermissionMapper(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalDecoder.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalDecoder.java new file mode 100644 index 00000000..675537e5 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalDecoder.java @@ -0,0 +1,54 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2016, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.wildfly.extras.creaper.commands.elytron.AbstractAddCustom; +import org.wildfly.extras.creaper.commands.foundation.offline.xml.GroovyXmlTransform; + +public final class AddCustomPrincipalDecoder extends AbstractAddCustom { + + private AddCustomPrincipalDecoder(Builder builder) { + super(builder); + } + + @Override + protected String getCustomTypeName() { + return "custom-principal-decoder"; + } + + @Override + protected GroovyXmlTransform.Builder getGroovyBuilder() { + return GroovyXmlTransform.of(AddCustomPrincipalDecoder.class); + } + + public static final class Builder extends AbstractAddCustom.Builder { + public Builder(String name) { + super(name); + } + + public AddCustomPrincipalDecoder build() { + checkClassNameAndModule(); + return new AddCustomPrincipalDecoder(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalTransformer.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalTransformer.java new file mode 100644 index 00000000..e2bf1f52 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalTransformer.java @@ -0,0 +1,54 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2016, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.wildfly.extras.creaper.commands.elytron.AbstractAddCustom; +import org.wildfly.extras.creaper.commands.foundation.offline.xml.GroovyXmlTransform; + +public final class AddCustomPrincipalTransformer extends AbstractAddCustom { + + private AddCustomPrincipalTransformer(Builder builder) { + super(builder); + } + + @Override + protected String getCustomTypeName() { + return "custom-principal-transformer"; + } + + @Override + protected GroovyXmlTransform.Builder getGroovyBuilder() { + return GroovyXmlTransform.of(AddCustomPrincipalTransformer.class); + } + + public static final class Builder extends AbstractAddCustom.Builder { + public Builder(String name) { + super(name); + } + + public AddCustomPrincipalTransformer build() { + checkClassNameAndModule(); + return new AddCustomPrincipalTransformer(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRealmMapper.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRealmMapper.java new file mode 100644 index 00000000..e79ef75c --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRealmMapper.java @@ -0,0 +1,54 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2016, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.wildfly.extras.creaper.commands.elytron.AbstractAddCustom; +import org.wildfly.extras.creaper.commands.foundation.offline.xml.GroovyXmlTransform; + +public final class AddCustomRealmMapper extends AbstractAddCustom { + + private AddCustomRealmMapper(Builder builder) { + super(builder); + } + + @Override + protected String getCustomTypeName() { + return "custom-realm-mapper"; + } + + @Override + protected GroovyXmlTransform.Builder getGroovyBuilder() { + return GroovyXmlTransform.of(AddCustomRealmMapper.class); + } + + public static final class Builder extends AbstractAddCustom.Builder { + public Builder(String name) { + super(name); + } + + public AddCustomRealmMapper build() { + checkClassNameAndModule(); + return new AddCustomRealmMapper(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleDecoder.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleDecoder.java new file mode 100644 index 00000000..62ab6bca --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleDecoder.java @@ -0,0 +1,54 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2016, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.wildfly.extras.creaper.commands.elytron.AbstractAddCustom; +import org.wildfly.extras.creaper.commands.foundation.offline.xml.GroovyXmlTransform; + +public final class AddCustomRoleDecoder extends AbstractAddCustom { + + private AddCustomRoleDecoder(Builder builder) { + super(builder); + } + + @Override + protected String getCustomTypeName() { + return "custom-role-decoder"; + } + + @Override + protected GroovyXmlTransform.Builder getGroovyBuilder() { + return GroovyXmlTransform.of(AddCustomRoleDecoder.class); + } + + public static final class Builder extends AbstractAddCustom.Builder { + public Builder(String name) { + super(name); + } + + public AddCustomRoleDecoder build() { + checkClassNameAndModule(); + return new AddCustomRoleDecoder(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleMapper.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleMapper.java new file mode 100644 index 00000000..b2665dde --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleMapper.java @@ -0,0 +1,32 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.wildfly.extras.creaper.commands.elytron.AbstractAddCustom; +import org.wildfly.extras.creaper.commands.foundation.offline.xml.GroovyXmlTransform; + +public final class AddCustomRoleMapper extends AbstractAddCustom { + + private AddCustomRoleMapper(Builder builder) { + super(builder); + } + + @Override + protected String getCustomTypeName() { + return "custom-role-mapper"; + } + + @Override + protected GroovyXmlTransform.Builder getGroovyBuilder() { + return GroovyXmlTransform.of(AddCustomRoleMapper.class); + } + + public static final class Builder extends AbstractAddCustom.Builder { + public Builder(String name) { + super(name); + } + + public AddCustomRoleMapper build() { + checkClassNameAndModule(); + return new AddCustomRoleMapper(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddLogicalPermissionMapper.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddLogicalPermissionMapper.java new file mode 100644 index 00000000..3ebb05d0 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddLogicalPermissionMapper.java @@ -0,0 +1,102 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddLogicalPermissionMapper implements OnlineCommand { + + private final String name; + private final LogicalOperation logicalOperation; + private final String left; + private final String right; + private final boolean replaceExisting; + + private AddLogicalPermissionMapper(Builder builder) { + this.name = builder.name; + this.logicalOperation = builder.logicalOperation; + this.left = builder.left; + this.right = builder.right; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address mapperAddress = Address.subsystem("elytron").and("logical-permission-mapper", name); + if (replaceExisting) { + ops.removeIfExists(mapperAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(mapperAddress, Values.empty() + .and("logical-operation", logicalOperation.name()) + .and("left", left) + .and("right", right)); + } + + public static final class Builder { + + private final String name; + private LogicalOperation logicalOperation; + private String left; + private String right; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the logical-permission-mapper must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the logical-permission-mapper must not be empty value"); + } + this.name = name; + } + + public Builder logicalOperation(LogicalOperation logicalOperation) { + this.logicalOperation = logicalOperation; + return this; + } + + public Builder left(String left) { + this.left = left; + return this; + } + + public Builder right(String right) { + this.right = right; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddLogicalPermissionMapper build() { + if (logicalOperation == null) { + throw new IllegalArgumentException("logical-operation must not be null"); + } + if (left == null) { + throw new IllegalArgumentException("left must not be null"); + } + if (right == null) { + throw new IllegalArgumentException("right must not be null"); + } + return new AddLogicalPermissionMapper(this); + } + } + + public static enum LogicalOperation { + + AND, UNLESS, OR, XOR + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddLogicalRoleMapper.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddLogicalRoleMapper.java new file mode 100644 index 00000000..9ee2a956 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddLogicalRoleMapper.java @@ -0,0 +1,97 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddLogicalRoleMapper implements OnlineCommand { + + private final String name; + private final LogicalOperation logicalOperation; + private final String left; + private final String right; + private final boolean replaceExisting; + + private AddLogicalRoleMapper(Builder builder) { + this.name = builder.name; + this.logicalOperation = builder.logicalOperation; + this.left = builder.left; + this.right = builder.right; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address mapperAddress = Address.subsystem("elytron").and("logical-role-mapper", name); + if (replaceExisting) { + ops.removeIfExists(mapperAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(mapperAddress, Values.empty() + .and("logical-operation", logicalOperation.name()) + .andOptional("left", left) + .andOptional("right", right)); + } + + public static final class Builder { + + private final String name; + private LogicalOperation logicalOperation; + private String left; + private String right; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the logical-role-mapper must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the logical-role-mapper must not be empty value"); + } + this.name = name; + } + + public Builder logicalOperation(LogicalOperation logicalOperation) { + this.logicalOperation = logicalOperation; + return this; + } + + public Builder left(String left) { + this.left = left; + return this; + } + + public Builder right(String right) { + this.right = right; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddLogicalRoleMapper build() { + if (logicalOperation == null) { + throw new IllegalArgumentException("logical-operation must not be null"); + } + return new AddLogicalRoleMapper(this); + } + + } + + public static enum LogicalOperation { + + AND, MINUS, OR, XOR + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddMappedRegexRealmMapper.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddMappedRegexRealmMapper.java new file mode 100644 index 00000000..fa8d2711 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddMappedRegexRealmMapper.java @@ -0,0 +1,133 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.jboss.dmr.ModelNode; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddMappedRegexRealmMapper implements OnlineCommand { + + private final String name; + private final String pattern; + private final String delegateRealmMapper; + private final List realmMappings; + private final boolean replaceExisting; + + private AddMappedRegexRealmMapper(Builder builder) { + this.name = builder.name; + this.pattern = builder.pattern; + this.delegateRealmMapper = builder.delegateRealmMapper; + this.realmMappings = builder.realmMappings; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address mapperAddress = Address.subsystem("elytron").and("mapped-regex-realm-mapper", name); + if (replaceExisting) { + ops.removeIfExists(mapperAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ModelNode realmMapNode = new ModelNode(); + for (RealmMapping realmMapping : realmMappings) { + realmMapNode.add(realmMapping.getFrom(), realmMapping.getTo()); + } + + ops.add(mapperAddress, Values.empty() + .and("pattern", pattern) + .andOptional("delegate-realm-mapper", delegateRealmMapper) + .and("realm-map", realmMapNode.asObject())); + } + + public static final class Builder { + + private String name; + private String pattern; + private String delegateRealmMapper; + private List realmMappings = new ArrayList(); + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the mapped-regex-realm-mapper must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the mapped-regex-realm-mapper must not be empty value"); + } + this.name = name; + } + + public Builder pattern(String pattern) { + this.pattern = pattern; + return this; + } + + public Builder delegateRealmMapper(String delegateRealmMapper) { + this.delegateRealmMapper = delegateRealmMapper; + return this; + } + + public Builder addRealmMappings(RealmMapping... realmMapping) { + if (realmMapping == null) { + throw new IllegalArgumentException("RealmMapping added to mapped-regex-realm-mapper must not be null"); + } + Collections.addAll(this.realmMappings, realmMapping); + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddMappedRegexRealmMapper build() { + if (pattern == null || pattern.isEmpty()) { + throw new IllegalArgumentException("pattern must not be null or empty"); + } + if (realmMappings == null || realmMappings.isEmpty()) { + throw new IllegalArgumentException("realm-mapping must not be null and must include at least one entry"); + } + return new AddMappedRegexRealmMapper(this); + } + } + + public static final class RealmMapping { + + private final String from; + private final String to; + + public RealmMapping(String from, String to) { + if (from == null) { + throw new IllegalArgumentException("from must not be null"); + } + if (to == null) { + throw new IllegalArgumentException("to must not be null"); + } + this.from = from; + this.to = to; + } + + public String getFrom() { + return from; + } + + public String getTo() { + return to; + } + + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddRegexPrincipalTransformer.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddRegexPrincipalTransformer.java new file mode 100644 index 00000000..f6c36966 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddRegexPrincipalTransformer.java @@ -0,0 +1,95 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddRegexPrincipalTransformer implements OnlineCommand { + + private final String name; + private final String pattern; + private final String replacement; + private final Boolean replaceAll; + private final boolean replaceExisting; + + private AddRegexPrincipalTransformer(Builder builder) { + this.name = builder.name; + this.pattern = builder.pattern; + this.replacement = builder.replacement; + this.replaceAll = builder.replaceAll; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address regexPrincipalTransformerAddress = Address.subsystem("elytron") + .and("regex-principal-transformer", name); + if (replaceExisting) { + ops.removeIfExists(regexPrincipalTransformerAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(regexPrincipalTransformerAddress, Values.empty() + .and("pattern", pattern) + .and("replacement", replacement) + .andOptional("replace-all", replaceAll)); + } + + public static final class Builder { + + private final String name; + private String pattern; + private String replacement; + private Boolean replaceAll; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the regex-principal-transformer must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the regex-principal-transformer must not be empty value"); + } + this.name = name; + } + + public Builder pattern(String pattern) { + this.pattern = pattern; + return this; + } + + public Builder replacement(String replacement) { + this.replacement = replacement; + return this; + } + + public Builder replaceAll(boolean replaceAll) { + this.replaceAll = replaceAll; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddRegexPrincipalTransformer build() { + if (pattern == null || pattern.isEmpty()) { + throw new IllegalArgumentException("Pattern must not be null and must have a minimum length of 1 character"); + } + if (replacement == null) { + throw new IllegalArgumentException("Replacement must not be null"); + } + return new AddRegexPrincipalTransformer(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddRegexValidatingPrincipalTransformer.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddRegexValidatingPrincipalTransformer.java new file mode 100644 index 00000000..b853dc11 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddRegexValidatingPrincipalTransformer.java @@ -0,0 +1,84 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddRegexValidatingPrincipalTransformer implements OnlineCommand { + + private final String name; + private final String pattern; + private final Boolean match; + private final boolean replaceExisting; + + private AddRegexValidatingPrincipalTransformer(Builder builder) { + this.name = builder.name; + this.pattern = builder.pattern; + this.match = builder.match; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address regexPrincipalTransformerAddress = Address.subsystem("elytron").and("regex-validating-principal-transformer", + name); + if (replaceExisting) { + ops.removeIfExists(regexPrincipalTransformerAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(regexPrincipalTransformerAddress, Values.empty() + .and("pattern", pattern) + .andOptional("match", match) + .andOptional("replace-all", match)); + } + + public static final class Builder { + + private final String name; + private String pattern; + private Boolean match; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the regex-validating-principal-transformer must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the regex-validating-principal-transformer must not be empty value"); + } + this.name = name; + } + + public Builder pattern(String pattern) { + this.pattern = pattern; + return this; + } + + public Builder match(boolean match) { + this.match = match; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddRegexValidatingPrincipalTransformer build() { + if (pattern == null || pattern.isEmpty()) { + throw new IllegalArgumentException("Pattern must not be null and must have a minimum length of 1 character"); + } + return new AddRegexValidatingPrincipalTransformer(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddSimplePermissionMapper.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddSimplePermissionMapper.java new file mode 100644 index 00000000..27f3c7f6 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddSimplePermissionMapper.java @@ -0,0 +1,288 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.jboss.dmr.ModelNode; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddSimplePermissionMapper implements OnlineCommand { + + private final String name; + private final MappingMode mappingMode; + private final List permissionMappings; + private final boolean replaceExisting; + + private AddSimplePermissionMapper(Builder builder) { + this.name = builder.name; + this.mappingMode = builder.mappingMode; + this.permissionMappings = builder.permissionMappings; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address mapperAddress = Address.subsystem("elytron").and("simple-permission-mapper", name); + if (replaceExisting) { + ops.removeIfExists(mapperAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + List permissionMappingsModelNodeList = null; + if (permissionMappings != null && !permissionMappings.isEmpty()) { + permissionMappingsModelNodeList = new ArrayList(); + for (PermissionMapping mapping : permissionMappings) { + ModelNode configNode = new ModelNode(); + if (mapping.getMatchAll() != null) { + configNode.add("match-all", mapping.getMatchAll()); + } + if (mapping.getRoles() != null && !mapping.getRoles().isEmpty()) { + ModelNode rolesList = new ModelNode().setEmptyList(); + for (String role : mapping.getRoles()) { + rolesList.add(role); + } + configNode.add("roles", rolesList); + } + if (mapping.getPrincipals() != null && !mapping.getPrincipals().isEmpty()) { + ModelNode principalsList = new ModelNode().setEmptyList(); + for (String principal : mapping.getPrincipals()) { + principalsList.add(principal); + } + configNode.add("principals", principalsList); + } + ModelNode permissionsModelNodeList = new ModelNode().setEmptyList(); + for (Permission permission : mapping.getPermissions()) { + ModelNode permissionNode = new ModelNode() + .add("class-name", permission.getClassName()); + if (permission.getAction() != null && !permission.getAction().isEmpty()) { + permissionNode.add("action", permission.getAction()); + } + if (permission.getModule() != null && !permission.getModule().isEmpty()) { + permissionNode.add("module", permission.getModule()); + } + if (permission.getTargetName() != null && !permission.getTargetName().isEmpty()) { + permissionNode.add("target-name", permission.getTargetName()); + } + permissionNode = permissionNode.asObject(); + permissionsModelNodeList.add(permissionNode); + } + configNode.add("permissions", permissionsModelNodeList); + configNode = configNode.asObject(); + permissionMappingsModelNodeList.add(configNode); + } + } + + String mappingModeValue = mappingMode == null ? null : mappingMode.name(); + + ops.add(mapperAddress, Values.empty() + .andOptional("mapping-mode", mappingModeValue) + .andListOptional(ModelNode.class, "permission-mappings", permissionMappingsModelNodeList)); + } + + + public static final class Builder { + + private final String name; + private MappingMode mappingMode; + private List permissionMappings = new ArrayList(); + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the simple-permission-mapper must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the simple-permission-mapper must not be empty value"); + } + this.name = name; + } + + public Builder mappingMode(MappingMode mappingMode) { + this.mappingMode = mappingMode; + return this; + } + + public Builder addPermissionMappings(PermissionMapping... permissionMappings) { + if (permissionMappings == null) { + throw new IllegalArgumentException("PermissionMapping added to simple-permission-mapper must not be null"); + } + Collections.addAll(this.permissionMappings, permissionMappings); + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddSimplePermissionMapper build() { + return new AddSimplePermissionMapper(this); + } + + } + + public static final class PermissionMapping { + + private final Boolean matchAll; + private final List roles; + private final List principals; + private final List permissions; + + private PermissionMapping(PermissionMappingBuilder builder) { + this.matchAll = builder.matchAll; + this.roles = builder.roles; + this.principals = builder.principals; + this.permissions = builder.permissions; + } + + public Boolean getMatchAll() { + return matchAll; + } + + public List getRoles() { + return roles; + } + + public List getPrincipals() { + return principals; + } + + public List getPermissions() { + return permissions; + } + + } + + public static final class PermissionMappingBuilder { + + private Boolean matchAll; + private List roles = new ArrayList(); + private List principals = new ArrayList(); + private List permissions = new ArrayList(); + + public PermissionMappingBuilder matchAll(Boolean matchAll) { + this.matchAll = matchAll; + return this; + } + + public PermissionMappingBuilder addRoles(String... roles) { + if (roles == null) { + throw new IllegalArgumentException("Roles added to permission-mapping of simple-permission-mapper must not be null"); + } + Collections.addAll(this.roles, roles); + return this; + } + + public PermissionMappingBuilder addPrincipals(String... principals) { + if (principals == null) { + throw new IllegalArgumentException("Principals added to permission-mapping of simple-permission-mapper must not be null"); + } + Collections.addAll(this.principals, principals); + return this; + } + + public PermissionMappingBuilder addPermissions(Permission... permissions) { + if (permissions == null) { + throw new IllegalArgumentException("Permissions added to permission-mapping of simple-permission-mapper must not be null"); + } + Collections.addAll(this.permissions, permissions); + return this; + } + + public PermissionMapping build() { + if (matchAll != null && !principals.isEmpty()) { + throw new IllegalArgumentException("Only one of principal and match-all can be used."); + } + if (matchAll != null && !roles.isEmpty()) { + throw new IllegalArgumentException("Only one of roles and match-all can be used."); + } + return new PermissionMapping(this); + } + + } + + public static final class Permission { + + private final String className; + private final String module; + private final String targetName; + private final String action; + + private Permission(PermissionBuilder builder) { + this.className = builder.className; + this.module = builder.module; + this.targetName = builder.targetName; + this.action = builder.action; + } + + public String getClassName() { + return className; + } + + public String getModule() { + return module; + } + + public String getTargetName() { + return targetName; + } + + public String getAction() { + return action; + } + + } + + public static final class PermissionBuilder { + + private String className; + private String module; + private String targetName; + private String action; + + public PermissionBuilder className(String className) { + this.className = className; + return this; + } + + public PermissionBuilder module(String module) { + this.module = module; + return this; + } + + public PermissionBuilder targetName(String targetName) { + this.targetName = targetName; + return this; + } + + public PermissionBuilder action(String action) { + this.action = action; + return this; + } + + public Permission build() { + if (className == null || className.isEmpty()) { + throw new IllegalArgumentException("class-name must not be null and must have a minimum length of 1 characters"); + } + return new Permission(this); + } + } + + public static enum MappingMode { + + AND, FIRST, OR, UNLESS, XOR + } + + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddSimpleRegexRealmMapper.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddSimpleRegexRealmMapper.java new file mode 100644 index 00000000..e3e0168c --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddSimpleRegexRealmMapper.java @@ -0,0 +1,82 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddSimpleRegexRealmMapper implements OnlineCommand { + + private final String name; + private final String pattern; + private final String delegateRealmMapper; + private final boolean replaceExisting; + + private AddSimpleRegexRealmMapper(Builder builder) { + this.name = builder.name; + this.pattern = builder.pattern; + this.delegateRealmMapper = builder.delegateRealmMapper; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address mapperAddress = Address.subsystem("elytron").and("simple-regex-realm-mapper", name); + if (replaceExisting) { + ops.removeIfExists(mapperAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(mapperAddress, Values.empty() + .and("pattern", pattern) + .andOptional("delegate-realm-mapper", delegateRealmMapper)); + } + + public static final class Builder { + + private String name; + private String pattern; + private String delegateRealmMapper; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the simple-regex-realm-mapper must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the simple-regex-realm-mapper must not be empty value"); + } + this.name = name; + } + + public Builder pattern(String pattern) { + this.pattern = pattern; + return this; + } + + public Builder delegateRealmMapper(String delegateRealmMapper) { + this.delegateRealmMapper = delegateRealmMapper; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddSimpleRegexRealmMapper build() { + if (pattern == null || pattern.isEmpty()) { + throw new IllegalArgumentException("pattern must not be null or empty"); + } + return new AddSimpleRegexRealmMapper(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddSimpleRoleDecoder.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddSimpleRoleDecoder.java new file mode 100644 index 00000000..704eed36 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddSimpleRoleDecoder.java @@ -0,0 +1,74 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddSimpleRoleDecoder implements OnlineCommand { + + private final String name; + private final String attribute; + private final boolean replaceExisting; + + private AddSimpleRoleDecoder(Builder builder) { + this.name = builder.name; + this.replaceExisting = builder.replaceExisting; + this.attribute = builder.attribute; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address simpleRoleDecoderAddress = Address.subsystem("elytron").and("simple-role-decoder", name); + if (replaceExisting) { + ops.removeIfExists(simpleRoleDecoderAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(simpleRoleDecoderAddress, Values.empty() + .and("attribute", attribute)); + } + + public static final class Builder { + + private final String name; + private String attribute; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the simple-role-decoder must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the simple-role-decoder must not be empty value"); + } + this.name = name; + } + + public Builder attribute(String attribute) { + this.attribute = attribute; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddSimpleRoleDecoder build() { + if (attribute == null || attribute.isEmpty()) { + throw new IllegalArgumentException("Attribute must not be null and must have a minimum length of 1 character"); + } + return new AddSimpleRoleDecoder(this); + } + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddX500AttributePrincipalDecoder.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddX500AttributePrincipalDecoder.java new file mode 100644 index 00000000..14e05f6c --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddX500AttributePrincipalDecoder.java @@ -0,0 +1,169 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.wildfly.extras.creaper.core.ServerVersion; + +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddX500AttributePrincipalDecoder implements OnlineCommand { + + private final String name; + private final String oid; + private final String attributeName; + private final String joiner; + private final Integer startSegment; + private final Integer maximumSegments; + private final Boolean reverse; + private final Boolean convert; + private final List requiredOids; + private final List requiredAttributes; + private final boolean replaceExisting; + + private AddX500AttributePrincipalDecoder(Builder builder) { + this.name = builder.name; + this.oid = builder.oid; + this.attributeName = builder.attributeName; + this.joiner = builder.joiner; + this.startSegment = builder.startSegment; + this.maximumSegments = builder.maximumSegments; + this.reverse = builder.reverse; + this.convert = builder.convert; + this.requiredOids = builder.requiredOids; + this.requiredAttributes = builder.requiredAttributes; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address x500AttributePrincipalDecoderAddress = Address.subsystem("elytron") + .and("x500-attribute-principal-decoder", name); + if (replaceExisting) { + ops.removeIfExists(x500AttributePrincipalDecoderAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(x500AttributePrincipalDecoderAddress, Values.empty() + .andOptional("oid", oid) + .andOptional("attribute-name", attributeName) + .andOptional("joiner", joiner) + .andOptional("start-segment", startSegment) + .andOptional("maximum-segments", maximumSegments) + .andOptional("reverse", reverse) + .andOptional("convert", convert) + .andListOptional(String.class, "required-oids", requiredOids) + .andListOptional(String.class, "required-attributes", requiredAttributes)); + + } + + public static final class Builder { + + private final String name; + private String oid; + private String attributeName; + private String joiner; + private Integer startSegment; + private Integer maximumSegments; + private Boolean reverse; + private Boolean convert; + private List requiredOids; + private List requiredAttributes; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the x500-attribute-principal-decoder must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the x500-attribute-principal-decoder must not be empty value"); + } + this.name = name; + } + + public Builder oid(String oid) { + this.oid = oid; + return this; + } + + public Builder attributeName(String attributeName) { + this.attributeName = attributeName; + return this; + } + + public Builder joiner(String joiner) { + this.joiner = joiner; + return this; + } + + public Builder startSegment(int startSegment) { + this.startSegment = startSegment; + return this; + } + + public Builder maximumSegments(int maximumSegments) { + this.maximumSegments = maximumSegments; + return this; + } + + public Builder reverse(boolean reverse) { + this.reverse = reverse; + return this; + } + + public Builder convert(boolean convert) { + this.convert = convert; + return this; + } + + public Builder addRequiredOids(String... requiredOids) { + if (requiredOids == null) { + throw new IllegalArgumentException("Required OIDs added to x500-attribute-principal-decoder must not be null"); + } + if (this.requiredOids == null) { + this.requiredOids = new ArrayList(); + } + + Collections.addAll(this.requiredOids, requiredOids); + return this; + } + + public Builder addRequiredAttributes(String... requiredAttributes) { + if (requiredAttributes == null) { + throw new IllegalArgumentException("Required attributes added to x500-attribute-principal-decoder must not be null"); + } + if (this.requiredAttributes == null) { + this.requiredAttributes = new ArrayList(); + } + + Collections.addAll(this.requiredAttributes, requiredAttributes); + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddX500AttributePrincipalDecoder build() { + boolean isOidEmpty = oid == null || oid.isEmpty(); + boolean isAttributeNameEmpty = attributeName == null || attributeName.isEmpty(); + + if ((isOidEmpty && isAttributeNameEmpty) || (!isOidEmpty && !isAttributeNameEmpty)) { + throw new IllegalArgumentException("Exactly one of [oid, attribute-name] must be configured."); + } + + return new AddX500AttributePrincipalDecoder(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/providerloader/AddAggregateProviders.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/providerloader/AddAggregateProviders.java new file mode 100644 index 00000000..3ef19bcf --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/providerloader/AddAggregateProviders.java @@ -0,0 +1,81 @@ +package org.wildfly.extras.creaper.commands.elytron.providerloader; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public class AddAggregateProviders implements OnlineCommand { + + private final String name; + private final List providers; + private final boolean replaceExisting; + + private AddAggregateProviders(Builder builder) { + this.name = builder.name; + this.providers = builder.providers; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address aggregatepProvidersAddress = Address.subsystem("elytron").and("aggregate-providers", name); + if (replaceExisting) { + ops.removeIfExists(aggregatepProvidersAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(aggregatepProvidersAddress, Values.empty() + .andList(String.class, "providers", providers)); + } + + public static final class Builder { + + private final String name; + private final List providers = new ArrayList(); + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the aggregate-providers must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the aggregate-providers must not be empty value"); + } + + this.name = name; + } + + public Builder providers(String... providers) { + if (providers == null) { + throw new IllegalArgumentException("Providers added to aggregate-providers must not be null"); + } + Collections.addAll(this.providers, providers); + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddAggregateProviders build() { + if (providers.size() < 2) { + throw new IllegalArgumentException("There must be at least two providers"); + } + return new AddAggregateProviders(this); + } + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/providerloader/AddProviderLoader.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/providerloader/AddProviderLoader.java new file mode 100644 index 00000000..97a03e0a --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/providerloader/AddProviderLoader.java @@ -0,0 +1,145 @@ +package org.wildfly.extras.creaper.commands.elytron.providerloader; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import org.wildfly.extras.creaper.core.ServerVersion; + +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public class AddProviderLoader implements OnlineCommand { + + private final String name; + private final List classNames; + private final Map configuration; + private final String module; + private final String path; + private final String relativeTo; + private final String argument; + private final boolean replaceExisting; + + private AddProviderLoader(Builder builder) { + this.name = builder.name; + this.classNames = builder.classNames; + this.configuration = builder.configuration; + this.module = builder.module; + this.path = builder.path; + this.relativeTo = builder.relativeTo; + this.argument = builder.argument; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address providerLoaderAddress = Address.subsystem("elytron").and("provider-loader", name); + if (replaceExisting) { + ops.removeIfExists(providerLoaderAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(providerLoaderAddress, Values.empty() + .andListOptional(String.class, "class-names", classNames) + .andObjectOptional("configuration", Values.fromMap(configuration)) + .andOptional("module", module) + .andOptional("path", path) + .andOptional("relative-to", relativeTo) + .andOptional("argument", argument)); + } + + public static final class Builder { + + private final String name; + private List classNames; + private Map configuration = new LinkedHashMap(); + private String module; + private String path; + private String relativeTo; + private String argument; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the provider-loader must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the provider-loader must not be empty value"); + } + this.name = name; + } + + public Builder classNames(String... classNames) { + if (classNames == null) { + throw new IllegalArgumentException("Class-names added to provider-loader must not be null"); + } + if (this.classNames == null) { + this.classNames = new ArrayList(); + } + + Collections.addAll(this.classNames, classNames); + return this; + } + + public Builder addConfiguration(String name, String value) { + if (name == null || name.isEmpty()) { + throw new IllegalArgumentException("Name of the configuration of the provider-loader must not be null"); + } + if (value == null || value.isEmpty()) { + throw new IllegalArgumentException("Value of the configuration of the provider-loader must not be null"); + } + configuration.put(name, value); + return this; + } + + public Builder module(String module) { + this.module = module; + return this; + } + + public Builder path(String path) { + this.path = path; + return this; + } + + public Builder relativeTo(String relativeTo) { + this.relativeTo = relativeTo; + return this; + } + + public Builder argument(String argument) { + this.argument = argument; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddProviderLoader build() { + boolean isConfiguration = configuration != null && !configuration.isEmpty(); + boolean isPath = path != null && !path.isEmpty(); + boolean isArgument = argument != null && !argument.isEmpty(); + + if ((isArgument && isPath) || (isArgument && isConfiguration) || (isPath && isConfiguration)) { + throw new IllegalArgumentException("There must be most one configuration approach chosen from [ argument, path, configuration ] "); + } + + return new AddProviderLoader(this); + } + + + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddAggregateRealm.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddAggregateRealm.java new file mode 100644 index 00000000..138f3fe5 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddAggregateRealm.java @@ -0,0 +1,87 @@ +package org.wildfly.extras.creaper.commands.elytron.realm; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddAggregateRealm implements OnlineCommand { + + private final String name; + private final String authenticationRealm; + private final String authorizationRealm; + private final boolean replaceExisting; + + private AddAggregateRealm(Builder builder) { + this.name = builder.name; + this.authenticationRealm = builder.authenticationRealm; + this.authorizationRealm = builder.authorizationRealm; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address securityRealmAddress = Address.subsystem("elytron").and("aggregate-realm", name); + if (replaceExisting) { + ops.removeIfExists(securityRealmAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(securityRealmAddress, Values.empty() + .and("authentication-realm", authenticationRealm) + .and("authorization-realm", authorizationRealm)); + } + + public static final class Builder { + + private final String name; + private String authenticationRealm; + private String authorizationRealm; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the aggregate-realm must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the aggregate-realm must not be empty value"); + } + + this.name = name; + } + + public Builder authenticationRealm(String authenticationRealm) { + this.authenticationRealm = authenticationRealm; + return this; + } + + public Builder authorizationRealm(String authorizationRealm) { + this.authorizationRealm = authorizationRealm; + return this; + } + + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddAggregateRealm build() { + if (authenticationRealm == null || authenticationRealm.isEmpty()) { + throw new IllegalArgumentException("authentication-realm must not be null or empty"); + } + if (authorizationRealm == null || authorizationRealm.isEmpty()) { + throw new IllegalArgumentException("authorization-realm must not be null or empty"); + } + return new AddAggregateRealm(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCachingRealm.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCachingRealm.java new file mode 100644 index 00000000..b6b182a6 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCachingRealm.java @@ -0,0 +1,127 @@ +package org.wildfly.extras.creaper.commands.elytron.realm; + +import org.wildfly.extras.creaper.commands.foundation.offline.xml.GroovyXmlTransform; +import org.wildfly.extras.creaper.commands.foundation.offline.xml.Subtree; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.offline.OfflineCommand; +import org.wildfly.extras.creaper.core.offline.OfflineCommandContext; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddCachingRealm implements OnlineCommand, OfflineCommand { + + private final String name; + private final String realm; + private final Integer maximumEntries; + private final Long maximumAge; + private final boolean replaceExisting; + + private AddCachingRealm(Builder builder) { + this.name = builder.name; + this.realm = builder.realm; + this.maximumEntries = builder.maximumEntries; + this.maximumAge = builder.maximumAge; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address securityRealmAddress = Address.subsystem("elytron").and("caching-realm", name); + if (replaceExisting) { + ops.removeIfExists(securityRealmAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(securityRealmAddress, Values.empty() + .and("realm", realm) + .andOptional("maximum-entries", maximumEntries) + .andOptional("maximum-age", maximumAge)); + } + + @Override + public void apply(OfflineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + ctx.client.apply(GroovyXmlTransform.of(AddCachingRealm.class) + .subtree("elytronSubsystem", Subtree.subsystem("elytron")) + .parameter("atrName", name) + .parameter("atrRealm", realm) + .parameter("atrMaximumEntries", maximumEntries) + .parameter("atrMaximumAge", maximumAge) + .parameter("atrReplaceExisting", replaceExisting) + .build()); + } + + public static final class Builder { + + private final String name; + private String realm; + private Integer maximumEntries; + private Long maximumAge; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the caching-realm must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the caching-realm must not be empty value"); + } + + this.name = name; + } + + /** + * A reference to a cacheable security realm. + */ + public Builder realm(String realm) { + this.realm = realm; + return this; + } + + /** + * The maximum number of entries to keep in the cache. Defaults to 16. + */ + public Builder maximumEntries(int maximumEntries) { + if (maximumEntries < 0) { + throw new IllegalArgumentException("maximum-entries must not be negative"); + } + this.maximumEntries = maximumEntries; + return this; + } + + /** + * The time in milliseconds that an item can stay in the cache. Defaults to -1. + */ + public Builder maximumAge(long maximumAge) { + this.maximumAge = maximumAge; + return this; + } + + /** + * Replace caching-realm with the same name, if exists. + */ + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddCachingRealm build() { + if (realm == null || realm.isEmpty()) { + throw new IllegalArgumentException("realm must not be null or empty"); + } + return new AddCachingRealm(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomModifiableRealm.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomModifiableRealm.java new file mode 100644 index 00000000..76dcbf9a --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomModifiableRealm.java @@ -0,0 +1,54 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2016, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.wildfly.extras.creaper.commands.elytron.realm; + +import org.wildfly.extras.creaper.commands.elytron.AbstractAddCustom; +import org.wildfly.extras.creaper.commands.foundation.offline.xml.GroovyXmlTransform; + +public final class AddCustomModifiableRealm extends AbstractAddCustom { + + private AddCustomModifiableRealm(Builder builder) { + super(builder); + } + + @Override + protected String getCustomTypeName() { + return "custom-modifiable-realm"; + } + + @Override + protected GroovyXmlTransform.Builder getGroovyBuilder() { + return GroovyXmlTransform.of(AddCustomModifiableRealm.class); + } + + public static final class Builder extends AbstractAddCustom.Builder { + public Builder(String name) { + super(name); + } + + public AddCustomModifiableRealm build() { + checkClassNameAndModule(); + return new AddCustomModifiableRealm(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomRealm.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomRealm.java new file mode 100644 index 00000000..b53cd0de --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomRealm.java @@ -0,0 +1,54 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2016, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.wildfly.extras.creaper.commands.elytron.realm; + +import org.wildfly.extras.creaper.commands.elytron.AbstractAddCustom; +import org.wildfly.extras.creaper.commands.foundation.offline.xml.GroovyXmlTransform; + +public final class AddCustomRealm extends AbstractAddCustom { + + private AddCustomRealm(Builder builder) { + super(builder); + } + + @Override + protected String getCustomTypeName() { + return "custom-realm"; + } + + @Override + protected GroovyXmlTransform.Builder getGroovyBuilder() { + return GroovyXmlTransform.of(AddCustomRealm.class); + } + + public static final class Builder extends AbstractAddCustom.Builder { + public Builder(String name) { + super(name); + } + + public AddCustomRealm build() { + checkClassNameAndModule(); + return new AddCustomRealm(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddFilesystemRealm.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddFilesystemRealm.java new file mode 100644 index 00000000..88ae964b --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddFilesystemRealm.java @@ -0,0 +1,105 @@ +package org.wildfly.extras.creaper.commands.elytron.realm; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddFilesystemRealm implements OnlineCommand { + + private final String name; + private final Integer levels; + private final String path; + private final String relativeTo; + private final Boolean encoded; + private final boolean replaceExisting; + + private AddFilesystemRealm(Builder builder) { + this.name = builder.name; + this.levels = builder.levels; + this.path = builder.path; + this.relativeTo = builder.relativeTo; + this.encoded = builder.encoded; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address securityRealmAddress = Address.subsystem("elytron").and("filesystem-realm", name); + if (replaceExisting) { + ops.removeIfExists(securityRealmAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(securityRealmAddress, Values.empty() + .and("path", path) + .andOptional("encoded", encoded) + .andOptional("levels", levels) + .andOptional("relative-to", relativeTo)); + + new Administration(ctx.client).reloadIfRequired(); + } + + + public static final class Builder { + + private final String name; + private Integer levels; + private String path; + private String relativeTo; + private Boolean encoded; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the filesystem-realm must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the filesystem-realm must not be empty value"); + } + this.name = name; + } + + public Builder levels(Integer levels) { + this.levels = levels; + return this; + } + + public Builder path(String path) { + this.path = path; + return this; + } + + public Builder relativeTo(String relativeTo) { + this.relativeTo = relativeTo; + return this; + } + + public Builder encoded(Boolean encoded) { + this.encoded = encoded; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddFilesystemRealm build() { + if (path == null || path.isEmpty()) { + throw new IllegalArgumentException("path must not be null and must have a minimum length of 1 characters"); + } + return new AddFilesystemRealm(this); + } + + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddIdentityRealm.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddIdentityRealm.java new file mode 100644 index 00000000..490a7c0c --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddIdentityRealm.java @@ -0,0 +1,101 @@ +package org.wildfly.extras.creaper.commands.elytron.realm; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddIdentityRealm implements OnlineCommand { + + private final String name; + private final String identity; + private final String attributeName; + private final List attributeValues; + private final boolean replaceExisting; + + private AddIdentityRealm(Builder builder) { + this.name = builder.name; + this.identity = builder.identity; + this.attributeName = builder.attributeName; + this.attributeValues = builder.attributeValues; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address identityRealmAddress = Address.subsystem("elytron").and("identity-realm", name); + if (replaceExisting) { + ops.removeIfExists(identityRealmAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(identityRealmAddress, Values.empty() + .and("identity", identity) + .andOptional("attribute-name", attributeName) + .andListOptional(String.class, "attribute-values", attributeValues)); + } + + public static final class Builder { + + private final String name; + private String identity; + private String attributeName; + private List attributeValues; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the identity-realm must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the identity-realm must not be empty value"); + } + this.name = name; + } + + public Builder identity(String identity) { + this.identity = identity; + return this; + } + + public Builder attributeName(String attributeName) { + this.attributeName = attributeName; + return this; + } + + public Builder attributeValues(String... attributeValues) { + if (attributeValues == null) { + throw new IllegalArgumentException("Attribute values added to identity-realm must not be null"); + } + if (this.attributeValues == null) { + this.attributeValues = new ArrayList(); + } + + Collections.addAll(this.attributeValues, attributeValues); + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddIdentityRealm build() { + if (identity == null || identity.isEmpty()) { + throw new IllegalArgumentException("Identity must not be null and must have a minimum length of 1 character"); + } + return new AddIdentityRealm(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddJdbcRealm.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddJdbcRealm.java new file mode 100644 index 00000000..f1be95e2 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddJdbcRealm.java @@ -0,0 +1,585 @@ +package org.wildfly.extras.creaper.commands.elytron.realm; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.jboss.dmr.ModelNode; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddJdbcRealm implements OnlineCommand { + + private final String name; + private final List principalQueries; + private final boolean replaceExisting; + + private AddJdbcRealm(Builder builder) { + this.name = builder.name; + this.replaceExisting = builder.replaceExisting; + this.principalQueries = builder.principalQueries; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address jdbcRealmAddress = Address.subsystem("elytron").and("jdbc-realm", name); + if (replaceExisting) { + ops.removeIfExists(jdbcRealmAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + List principalQueryNodeList = new ArrayList(); + for (PrincipalQuery principalQuery : principalQueries) { + ModelNode principalQueryNode = new ModelNode(); + principalQueryNode.add("sql", principalQuery.getSql()); + principalQueryNode.add("data-source", principalQuery.getDataSource()); + + if (principalQuery.getClearPasswordMapper() != null) { + ModelNode mapperNode = new ModelNode(); + mapperNode.add("password-index", principalQuery.getClearPasswordMapper().getPasswordIndex()); + mapperNode = mapperNode.asObject(); + principalQueryNode.add("clear-password-mapper", mapperNode); + } + if (principalQuery.getBcryptMapper() != null) { + ModelNode mapperNode = new ModelNode(); + mapperNode.add("password-index", principalQuery.getBcryptMapper().getPasswordIndex()); + mapperNode.add("salt-index", principalQuery.getBcryptMapper().getSaltIndex()); + mapperNode.add("iteration-count-index", principalQuery.getBcryptMapper().getIterationCountIndex()); + mapperNode = mapperNode.asObject(); + principalQueryNode.add("bcrypt-mapper", mapperNode); + } + if (principalQuery.getSimpleDigestMapper() != null) { + ModelNode mapperNode = new ModelNode(); + mapperNode.add("password-index", principalQuery.getSimpleDigestMapper().getPasswordIndex()); + mapperNode.add("algorithm", principalQuery.getSimpleDigestMapper().getAlgorithm()); + mapperNode = mapperNode.asObject(); + principalQueryNode.add("simple-digest-mapper", mapperNode); + } + if (principalQuery.getSaltedSimpleDigestMapper() != null) { + ModelNode mapperNode = new ModelNode(); + mapperNode.add("password-index", principalQuery.getSaltedSimpleDigestMapper().getPasswordIndex()); + mapperNode.add("salt-index", principalQuery.getSaltedSimpleDigestMapper().getSaltIndex()); + mapperNode.add("algorithm", principalQuery.getSaltedSimpleDigestMapper().getAlgorithm()); + mapperNode = mapperNode.asObject(); + principalQueryNode.add("salted-simple-digest-mapper", mapperNode); + } + if (principalQuery.getScramMapper() != null) { + ModelNode mapperNode = new ModelNode(); + mapperNode.add("password-index", principalQuery.getScramMapper().getPasswordIndex()); + mapperNode.add("salt-index", principalQuery.getScramMapper().getSaltIndex()); + mapperNode.add("iteration-count-index", principalQuery.getScramMapper().getIterationCountIndex()); + mapperNode.add("algorithm", principalQuery.getScramMapper().getAlgorithm()); + mapperNode = mapperNode.asObject(); + principalQueryNode.add("scram-mapper", mapperNode); + } + + if (principalQuery.getAttributeMapping() != null && !principalQuery.getAttributeMapping().isEmpty()) { + ModelNode attributeMappingNodeList = new ModelNode().setEmptyList(); + for (AttributeMapping attributeMapping : principalQuery.getAttributeMapping()) { + ModelNode attributeMappingNode = new ModelNode(); + attributeMappingNode.add("index", attributeMapping.getIndex()); + attributeMappingNode.add("to", attributeMapping.getTo()); + attributeMappingNode = attributeMappingNode.asObject(); + attributeMappingNodeList.add(attributeMappingNode); + } + principalQueryNode.add("attribute-mapping", attributeMappingNodeList); + } + + principalQueryNode = principalQueryNode.asObject(); + principalQueryNodeList.add(principalQueryNode); + } + + ops.add(jdbcRealmAddress, Values.empty() + .andList(ModelNode.class, "principal-query", principalQueryNodeList)); + } + + public static final class Builder { + + private final String name; + private List principalQueries; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the jdbc-realm must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the jdbc-realm must not be empty value"); + } + this.name = name; + } + + public Builder principalQueries(PrincipalQuery... principalQueries) { + if (principalQueries == null) { + throw new IllegalArgumentException("Principal queries added to jdbc-realm must not be null"); + } + if (this.principalQueries == null) { + this.principalQueries = new ArrayList(); + } + Collections.addAll(this.principalQueries, principalQueries); + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddJdbcRealm build() { + if (principalQueries == null || principalQueries.isEmpty()) { + throw new IllegalArgumentException("Principal queries must not be null and must include at least one entry"); + } + return new AddJdbcRealm(this); + } + + } + + public static final class PrincipalQuery { + + private final String sql; + private final String dataSource; + private final List attributeMapping; + private final ClearPasswordMapper clearPasswordMapper; + private final BcryptMapper bcryptMapper; + private final SimpleDigestMapper simpleDigestMapper; + private final SaltedSimpleDigestMapper saltedSimpleDigestMapper; + private final ScramMapper scramMapper; + + private PrincipalQuery(PrincipalQueryBuilder builder) { + this.sql = builder.sql; + this.dataSource = builder.dataSource; + this.attributeMapping = builder.attributeMapping; + this.clearPasswordMapper = builder.clearPasswordMapper; + this.bcryptMapper = builder.bcryptMapper; + this.simpleDigestMapper = builder.simpleDigestMapper; + this.saltedSimpleDigestMapper = builder.saltedSimpleDigestMapper; + this.scramMapper = builder.scramMapper; + } + + public String getSql() { + return sql; + } + + public String getDataSource() { + return dataSource; + } + + public List getAttributeMapping() { + return attributeMapping; + } + + public ClearPasswordMapper getClearPasswordMapper() { + return clearPasswordMapper; + } + + public BcryptMapper getBcryptMapper() { + return bcryptMapper; + } + + public SimpleDigestMapper getSimpleDigestMapper() { + return simpleDigestMapper; + } + + public SaltedSimpleDigestMapper getSaltedSimpleDigestMapper() { + return saltedSimpleDigestMapper; + } + + public ScramMapper getScramMapper() { + return scramMapper; + } + + } + + public static final class PrincipalQueryBuilder { + + private String sql; + private String dataSource; + private List attributeMapping; + private ClearPasswordMapper clearPasswordMapper; + private BcryptMapper bcryptMapper; + private SimpleDigestMapper simpleDigestMapper; + private SaltedSimpleDigestMapper saltedSimpleDigestMapper; + private ScramMapper scramMapper; + + public PrincipalQueryBuilder sql(String sql) { + this.sql = sql; + return this; + } + + public PrincipalQueryBuilder dataSource(String dataSource) { + this.dataSource = dataSource; + return this; + } + + public PrincipalQueryBuilder attributeMapping(AttributeMapping... attributeMapping) { + if (attributeMapping == null) { + throw new IllegalArgumentException("Attribute mappings added to principal-query must not be null"); + } + if (this.attributeMapping == null) { + this.attributeMapping = new ArrayList(); + } + Collections.addAll(this.attributeMapping, attributeMapping); + return this; + } + + public PrincipalQueryBuilder clearPasswordMapper(ClearPasswordMapper clearPasswordMapper) { + this.clearPasswordMapper = clearPasswordMapper; + return this; + } + + public PrincipalQueryBuilder bcryptMapper(BcryptMapper bcryptMapper) { + this.bcryptMapper = bcryptMapper; + return this; + } + + public PrincipalQueryBuilder simpleDigestMapper(SimpleDigestMapper simpleDigestMapper) { + this.simpleDigestMapper = simpleDigestMapper; + return this; + } + + public PrincipalQueryBuilder saltedSimpleDigestMapper(SaltedSimpleDigestMapper saltedSimpleDigestMapper) { + this.saltedSimpleDigestMapper = saltedSimpleDigestMapper; + return this; + } + + public PrincipalQueryBuilder scramMapper(ScramMapper scramMapper) { + this.scramMapper = scramMapper; + return this; + } + + public PrincipalQuery build() { + + if (sql == null || sql.isEmpty()) { + throw new IllegalArgumentException("sql must not be null or empty"); + } + + if (dataSource == null || dataSource.isEmpty()) { + throw new IllegalArgumentException("Data source must not be null or empty"); + } + + return new PrincipalQuery(this); + } + + } + + public static final class AttributeMapping { + + private final Integer index; + private final String to; + + private AttributeMapping(AttributeMappingBuilder builder) { + this.index = builder.index; + this.to = builder.to; + } + + public Integer getIndex() { + return index; + } + + public String getTo() { + return to; + } + } + + public static final class AttributeMappingBuilder { + + private Integer index; + private String to; + + public AttributeMappingBuilder index(Integer index) { + this.index = index; + return this; + } + + public AttributeMappingBuilder to(String to) { + this.to = to; + return this; + } + + public AttributeMapping build() { + if (index == null) { + throw new IllegalArgumentException("Index of the attribute-mapping must be specified as non null value"); + } + if (to == null || to.isEmpty()) { + throw new IllegalArgumentException("Attribute to of the attribute-mapping must be specified as non empty value"); + } + return new AttributeMapping(this); + } + } + + public static final class ClearPasswordMapper { + + private final Integer passwordIndex; + + private ClearPasswordMapper(ClearPasswordMapperBuilder builder) { + this.passwordIndex = builder.passwordIndex; + } + + public Integer getPasswordIndex() { + return passwordIndex; + } + } + + public static final class ClearPasswordMapperBuilder { + + private Integer passwordIndex; + + public ClearPasswordMapperBuilder passwordIndex(Integer passwordIndex) { + this.passwordIndex = passwordIndex; + return this; + } + + public ClearPasswordMapper build() { + if (passwordIndex == null) { + throw new IllegalArgumentException("Password index of the clear password mapper must be specified as non null value"); + } + return new ClearPasswordMapper(this); + } + } + + public static final class SimpleDigestMapper { + + private final Integer passwordIndex; + private final String algorithm; + + private SimpleDigestMapper(SimpleDigestMapperBuilder builder) { + this.passwordIndex = builder.passwordIndex; + this.algorithm = builder.algorithm; + } + + public Integer getPasswordIndex() { + return passwordIndex; + } + + public String getAlgorithm() { + return algorithm; + } + + } + + public static final class SimpleDigestMapperBuilder { + + private Integer passwordIndex; + private String algorithm; + + public SimpleDigestMapperBuilder passwordIndex(Integer passwordIndex) { + this.passwordIndex = passwordIndex; + return this; + } + + public SimpleDigestMapperBuilder algorithm(String algorithm) { + this.algorithm = algorithm; + return this; + } + + public SimpleDigestMapper build() { + if (passwordIndex == null) { + throw new IllegalArgumentException("Password index of the simple digest password mapper must be specified as non null value"); + } + return new SimpleDigestMapper(this); + } + } + + public static final class SaltedSimpleDigestMapper { + + private final Integer passwordIndex; + private final Integer saltIndex; + private final String algorithm; + + private SaltedSimpleDigestMapper(SaltedSimpleDigestMapperBuilder builder) { + this.passwordIndex = builder.passwordIndex; + this.saltIndex = builder.saltIndex; + this.algorithm = builder.algorithm; + } + + public Integer getPasswordIndex() { + return passwordIndex; + } + + public Integer getSaltIndex() { + return saltIndex; + } + + public String getAlgorithm() { + return algorithm; + } + + } + + public static final class SaltedSimpleDigestMapperBuilder { + + private Integer passwordIndex; + private Integer saltIndex; + private String algorithm; + + public SaltedSimpleDigestMapperBuilder passwordIndex(Integer passwordIndex) { + this.passwordIndex = passwordIndex; + return this; + } + + public SaltedSimpleDigestMapperBuilder saltIndex(Integer saltIndex) { + this.saltIndex = saltIndex; + return this; + } + + public SaltedSimpleDigestMapperBuilder algorithm(String algorithm) { + this.algorithm = algorithm; + return this; + } + + public SaltedSimpleDigestMapper build() { + if (passwordIndex == null) { + throw new IllegalArgumentException("Password index of the salted simple digest password mapper must be specified as non null value"); + } + if (saltIndex == null) { + throw new IllegalArgumentException("Salt index of the salted simple digest password mapper must be specified as non null value"); + } + return new SaltedSimpleDigestMapper(this); + } + } + + public static final class BcryptMapper { + + private final Integer passwordIndex; + private final Integer saltIndex; + private final Integer iterationCountIndex; + + private BcryptMapper(BcryptMapperBuilder builder) { + this.passwordIndex = builder.passwordIndex; + this.saltIndex = builder.saltIndex; + this.iterationCountIndex = builder.iterationCountIndex; + } + + public Integer getPasswordIndex() { + return passwordIndex; + } + + public Integer getSaltIndex() { + return saltIndex; + } + + public Integer getIterationCountIndex() { + return iterationCountIndex; + } + + } + + public static final class BcryptMapperBuilder { + + private Integer passwordIndex; + private Integer saltIndex; + private Integer iterationCountIndex; + + public BcryptMapperBuilder passwordIndex(Integer passwordIndex) { + this.passwordIndex = passwordIndex; + return this; + } + + public BcryptMapperBuilder saltIndex(Integer saltIndex) { + this.saltIndex = saltIndex; + return this; + } + + public BcryptMapperBuilder iterationCountIndex(Integer iterationCountIndex) { + this.iterationCountIndex = iterationCountIndex; + return this; + } + + public BcryptMapper build() { + if (passwordIndex == null) { + throw new IllegalArgumentException("Password index of the bcrypt password mapper must be specified as non null value"); + } + if (saltIndex == null) { + throw new IllegalArgumentException("Salt index of the bcrypt password mapper must be specified as non null value"); + } + if (iterationCountIndex == null) { + throw new IllegalArgumentException("Algorithm of the bcrypt password mapper must be specified as non null value"); + } + return new BcryptMapper(this); + } + } + + public static final class ScramMapper { + + private final Integer passwordIndex; + private final Integer saltIndex; + private final Integer iterationCountIndex; + private final String algorithm; + + private ScramMapper(ScramMapperBuilder builder) { + this.passwordIndex = builder.passwordIndex; + this.saltIndex = builder.saltIndex; + this.iterationCountIndex = builder.iterationCountIndex; + this.algorithm = builder.algorithm; + } + + public Integer getPasswordIndex() { + return passwordIndex; + } + + public Integer getSaltIndex() { + return saltIndex; + } + + public Integer getIterationCountIndex() { + return iterationCountIndex; + } + + public String getAlgorithm() { + return algorithm; + } + + } + + public static final class ScramMapperBuilder { + + private Integer passwordIndex; + private Integer saltIndex; + private Integer iterationCountIndex; + private String algorithm; + + public ScramMapperBuilder passwordIndex(Integer passwordIndex) { + this.passwordIndex = passwordIndex; + return this; + } + + public ScramMapperBuilder saltIndex(Integer saltIndex) { + this.saltIndex = saltIndex; + return this; + } + + public ScramMapperBuilder iterationCountIndex(Integer iterationCountIndex) { + this.iterationCountIndex = iterationCountIndex; + return this; + } + + public ScramMapperBuilder algorithm(String algorithm) { + this.algorithm = algorithm; + return this; + } + + public ScramMapper build() { + if (passwordIndex == null) { + throw new IllegalArgumentException("Password index of the scram mapper must be specified as non null value"); + } + if (saltIndex == null) { + throw new IllegalArgumentException("Salt index of the scram mapper must be specified as non null value"); + } + if (iterationCountIndex == null) { + throw new IllegalArgumentException("Algorithm of the scram mapper must be specified as non null value"); + } + return new ScramMapper(this); + } + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddKeyStoreRealm.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddKeyStoreRealm.java new file mode 100644 index 00000000..96ea2f26 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddKeyStoreRealm.java @@ -0,0 +1,74 @@ +package org.wildfly.extras.creaper.commands.elytron.realm; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddKeyStoreRealm implements OnlineCommand { + + private final String name; + private final String keyStore; + private final boolean replaceExisting; + + private AddKeyStoreRealm(Builder builder) { + this.name = builder.name; + this.keyStore = builder.keyStore; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address securityRealmAddress = Address.subsystem("elytron").and("key-store-realm", name); + if (replaceExisting) { + ops.removeIfExists(securityRealmAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(securityRealmAddress, Values.empty() + .and("key-store", keyStore)); + } + + public static final class Builder { + + private final String name; + private String keyStore; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the key-store-realm must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the key-store-realm must not be empty value"); + } + + this.name = name; + } + + public Builder keyStore(String keyStore) { + this.keyStore = keyStore; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddKeyStoreRealm build() { + if (keyStore == null || keyStore.isEmpty()) { + throw new IllegalArgumentException("key-store must not be null or empty string"); + } + return new AddKeyStoreRealm(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddLdapRealm.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddLdapRealm.java new file mode 100644 index 00000000..ea14d092 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddLdapRealm.java @@ -0,0 +1,744 @@ +package org.wildfly.extras.creaper.commands.elytron.realm; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.jboss.dmr.ModelNode; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddLdapRealm implements OnlineCommand { + + private final String name; + private final String dirContext; + private final Boolean directVerification; + private final Boolean allowBlankPassword; + private final IdentityMapping identityMapping; + private final boolean replaceExisting; + + private AddLdapRealm(Builder builder) { + this.name = builder.name; + this.dirContext = builder.dirContext; + this.directVerification = builder.directVerification; + this.allowBlankPassword = builder.allowBlankPassword; + this.identityMapping = builder.identityMapping; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address realmAddress = Address.subsystem("elytron").and("ldap-realm", name); + if (replaceExisting) { + ops.removeIfExists(realmAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ModelNode identityMappingModelNode = new ModelNode(); + identityMappingModelNode.add("rdn-identifier", identityMapping.getRdnIdentifier()); + addOptionalToModelNode(identityMappingModelNode, "search-base-dn", identityMapping.getSearchBaseDn()); + addOptionalToModelNode(identityMappingModelNode, "use-recursive-search", + identityMapping.getUseRecursiveSearch()); + addOptionalToModelNode(identityMappingModelNode, "filter-name", identityMapping.getFilterName()); + addOptionalToModelNode(identityMappingModelNode, "iterator-filter", identityMapping.getIteratorFilter()); + addOptionalToModelNode(identityMappingModelNode, "new-identity-parent-dn", + identityMapping.getNewIdentityParentDn()); + if (identityMapping.getAttributeMappings() != null && !identityMapping.getAttributeMappings().isEmpty()) { + List newAttributeMappingNodeList = new ArrayList(); + for (AttributeMapping attributeMapping : identityMapping.getAttributeMappings()) { + ModelNode node = new ModelNode(); + addOptionalToModelNode(node, "from", attributeMapping.getFrom()); + addOptionalToModelNode(node, "to", attributeMapping.getTo()); + addOptionalToModelNode(node, "filter", attributeMapping.getFilter()); + addOptionalToModelNode(node, "filter-base-dn", attributeMapping.getFilterBaseDn()); + addOptionalToModelNode(node, "extract-rdn", attributeMapping.getExtractRdn()); + addOptionalToModelNode(node, "search-recursive", attributeMapping.getSearchRecursive()); + addOptionalToModelNode(node, "role-recursion", attributeMapping.getRoleRecursion()); + addOptionalToModelNode(node, "role-recursion-name", attributeMapping.getRoleRecursionName()); + addOptionalToModelNode(node, "reference", attributeMapping.getReference()); + node = node.asObject(); + newAttributeMappingNodeList.add(node); + } + ModelNode attributeMappingNode = new ModelNode(); + attributeMappingNode.set(newAttributeMappingNodeList); + identityMappingModelNode.add("attribute-mapping", attributeMappingNode); + } + if (identityMapping.getUserPasswordMapper() != null) { + ModelNode node = new ModelNode(); + node.add("from", identityMapping.getUserPasswordMapper().getFrom()); + addOptionalToModelNode(node, "writable", identityMapping.getUserPasswordMapper().getWritable()); + addOptionalToModelNode(node, "verifiable", identityMapping.getUserPasswordMapper().getVerifiable()); + identityMappingModelNode.add("user-password-mapper", node.asObject()); + } + if (identityMapping.getOtpCredentialMapper() != null) { + ModelNode node = new ModelNode(); + node.add("algorithm-from", identityMapping.getOtpCredentialMapper().getAlgorithmFrom()); + node.add("hash-from", identityMapping.getOtpCredentialMapper().getHashFrom()); + node.add("seed-from", identityMapping.getOtpCredentialMapper().getSeedFrom()); + node.add("sequence-from", identityMapping.getOtpCredentialMapper().getSequenceFrom()); + identityMappingModelNode.add("otp-credential-mapper", node.asObject()); + } + if (identityMapping.getX509CredentialMapper() != null) { + ModelNode node = new ModelNode(); + addOptionalToModelNode(node, "digest-from", identityMapping.getX509CredentialMapper().getDigestFrom()); + addOptionalToModelNode(node, "digest-algorithm", + identityMapping.getX509CredentialMapper().getDigestAlgorithm()); + addOptionalToModelNode(node, "certificate-from", + identityMapping.getX509CredentialMapper().getCertificateFrom()); + addOptionalToModelNode(node, "serial-number-from", + identityMapping.getX509CredentialMapper().getSerialNumberFrom()); + addOptionalToModelNode(node, "subject-dn-from", + identityMapping.getX509CredentialMapper().getSubjectDnFrom()); + identityMappingModelNode.add("x509-credential-mapper", node.asObject()); + } + if (identityMapping.getNewIdentityAttributes() != null + && !identityMapping.getNewIdentityAttributes().isEmpty()) { + List newIdentityAttributesNodeList = new ArrayList(); + for (NewIdentityAttributes newIdentityAttribute : identityMapping.getNewIdentityAttributes()) { + ModelNode attributeNode = new ModelNode(); + addOptionalToModelNode(attributeNode, "name", newIdentityAttribute.getName()); + + ModelNode valuesList = new ModelNode().setEmptyList(); + for (String value : newIdentityAttribute.getValues()) { + valuesList.add(value); + } + attributeNode.add("value", valuesList); + + attributeNode = attributeNode.asObject(); + newIdentityAttributesNodeList.add(attributeNode); + } + ModelNode newIdentityAttributesNode = new ModelNode(); + newIdentityAttributesNode.set(newIdentityAttributesNodeList); + identityMappingModelNode.add("new-identity-attributes", newIdentityAttributesNode); + } + + ops.add(realmAddress, Values.empty() + .and("dir-context", dirContext) + .andOptional("direct-verification", directVerification) + .andOptional("allow-blank-password", allowBlankPassword) + .and("identity-mapping", identityMappingModelNode.asObject())); + + } + + private void addOptionalToModelNode(ModelNode node, String name, String value) { + if (value != null && !value.isEmpty()) { + node.add(name, value); + } + } + + private void addOptionalToModelNode(ModelNode node, String name, Boolean value) { + if (value != null) { + node.add(name, value); + } + } + + private void addOptionalToModelNode(ModelNode node, String name, Integer value) { + if (value != null) { + node.add(name, value); + } + } + + public static final class Builder { + + private final String name; + private String dirContext; + private Boolean directVerification; + private Boolean allowBlankPassword; + private IdentityMapping identityMapping; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the ldap-realm must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the ldap-realm must not be empty value"); + } + this.name = name; + } + + public Builder dirContext(String dirContext) { + this.dirContext = dirContext; + return this; + } + + public Builder directVerification(Boolean directVerification) { + this.directVerification = directVerification; + return this; + } + + public Builder allowBlankPassword(Boolean allowBlankPassword) { + this.allowBlankPassword = allowBlankPassword; + return this; + } + + public Builder identityMapping(IdentityMapping identityMapping) { + this.identityMapping = identityMapping; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddLdapRealm build() { + if (dirContext == null || dirContext.isEmpty()) { + throw new IllegalArgumentException("dir-context must not be null and must have a minimum length of 1 characters"); + } + if (identityMapping == null) { + throw new IllegalArgumentException("identity-mapping must not be null"); + } + return new AddLdapRealm(this); + } + } + + public static final class IdentityMapping { + + private final String rdnIdentifier; + private final String searchBaseDn; + private final Boolean useRecursiveSearch; + private final String filterName; + private final String iteratorFilter; + private final String newIdentityParentDn; + private final List attributeMappings; + private final UserPasswordMapper userPasswordMapper; + private final OtpCredentialMapper otpCredentialMapper; + private final X509CredentialMapper x509CredentialMapper; + private final List newIdentityAttributes; + + private IdentityMapping(IdentityMappingBuilder builder) { + this.rdnIdentifier = builder.rdnIdentifier; + this.searchBaseDn = builder.searchBaseDn; + this.useRecursiveSearch = builder.useRecursiveSearch; + this.filterName = builder.filterName; + this.iteratorFilter = builder.iteratorFilter; + this.newIdentityParentDn = builder.newIdentityParentDn; + this.attributeMappings = builder.attributeMappings; + this.userPasswordMapper = builder.userPasswordMapper; + this.otpCredentialMapper = builder.otpCredentialMapper; + this.newIdentityAttributes = builder.newIdentityAttributes; + this.x509CredentialMapper = builder.x509CredentialMapper; + } + + public String getRdnIdentifier() { + return rdnIdentifier; + } + + public String getSearchBaseDn() { + return searchBaseDn; + } + + public Boolean getUseRecursiveSearch() { + return useRecursiveSearch; + } + + public String getFilterName() { + return filterName; + } + + public String getIteratorFilter() { + return iteratorFilter; + } + + public String getNewIdentityParentDn() { + return newIdentityParentDn; + } + + public List getAttributeMappings() { + return attributeMappings; + } + + public UserPasswordMapper getUserPasswordMapper() { + return userPasswordMapper; + } + + public OtpCredentialMapper getOtpCredentialMapper() { + return otpCredentialMapper; + } + + public X509CredentialMapper getX509CredentialMapper() { + return x509CredentialMapper; + } + + public List getNewIdentityAttributes() { + return newIdentityAttributes; + } + + } + + public static final class IdentityMappingBuilder { + + private String rdnIdentifier; + private String searchBaseDn; + private Boolean useRecursiveSearch; + private String filterName; + private String iteratorFilter; + private String newIdentityParentDn; + private List attributeMappings = new ArrayList(); + private UserPasswordMapper userPasswordMapper; + private OtpCredentialMapper otpCredentialMapper; + private X509CredentialMapper x509CredentialMapper; + private List newIdentityAttributes = new ArrayList(); + + public IdentityMappingBuilder rdnIdentifier(String rdnIdentifier) { + this.rdnIdentifier = rdnIdentifier; + return this; + } + + public IdentityMappingBuilder searchBaseDn(String searchBaseDn) { + this.searchBaseDn = searchBaseDn; + return this; + } + + public IdentityMappingBuilder useRecursiveSearch(Boolean useRecursiveSearch) { + this.useRecursiveSearch = useRecursiveSearch; + return this; + } + + public IdentityMappingBuilder filterName(String filterName) { + this.filterName = filterName; + return this; + } + + public IdentityMappingBuilder iteratorFilter(String iteratorFilter) { + this.iteratorFilter = iteratorFilter; + return this; + } + + public IdentityMappingBuilder newIdentityParentDn(String newIdentityParentDn) { + this.newIdentityParentDn = newIdentityParentDn; + return this; + } + + public IdentityMappingBuilder addAttributeMappings(AttributeMapping... attributeMappings) { + if (attributeMappings == null) { + throw new IllegalArgumentException("AttributeMappings added to ldap-realm must not be null"); + } + Collections.addAll(this.attributeMappings, attributeMappings); + return this; + } + + public IdentityMappingBuilder userPasswordMapper(UserPasswordMapper userPasswordMapper) { + this.userPasswordMapper = userPasswordMapper; + return this; + } + + public IdentityMappingBuilder otpCredentialMapper(OtpCredentialMapper otpCredentialMapper) { + this.otpCredentialMapper = otpCredentialMapper; + return this; + } + + public IdentityMappingBuilder x509CredentialMapper( + X509CredentialMapper x509CredentialMapper) { + this.x509CredentialMapper = x509CredentialMapper; + return this; + } + + public IdentityMappingBuilder addNewIdentityAttributes(NewIdentityAttributes... newIdentityAttributes) { + if (newIdentityAttributes == null) { + throw new IllegalArgumentException("NewIdentityAttributes added to ldap-realm must not be null"); + } + Collections.addAll(this.newIdentityAttributes, newIdentityAttributes); + return this; + } + + public IdentityMapping build() { + if (rdnIdentifier == null || rdnIdentifier.isEmpty()) { + throw new IllegalArgumentException("rdn-identifier must not be null and must have a minimum length of 1 characters"); + } + return new IdentityMapping(this); + } + } + + public static final class AttributeMapping { + + private final String from; + private final String to; + private final String filter; + private final String filterBaseDn; + private final String extractRdn; + private final Boolean searchRecursive; + private final Integer roleRecursion; + private final String roleRecursionName; + private final String reference; + + private AttributeMapping(AttributeMappingBuilder builder) { + this.from = builder.from; + this.to = builder.to; + this.filter = builder.filter; + this.filterBaseDn = builder.filterBaseDn; + this.extractRdn = builder.extractRdn; + this.searchRecursive = builder.searchRecursive; + this.roleRecursion = builder.roleRecursion; + this.roleRecursionName = builder.roleRecursionName; + this.reference = builder.reference; + } + + public String getFrom() { + return from; + } + + public String getTo() { + return to; + } + + public String getFilter() { + return filter; + } + + public String getFilterBaseDn() { + return filterBaseDn; + } + + public String getExtractRdn() { + return extractRdn; + } + + public Boolean getSearchRecursive() { + return searchRecursive; + } + + public Integer getRoleRecursion() { + return roleRecursion; + } + + public String getRoleRecursionName() { + return roleRecursionName; + } + + public String getReference() { + return reference; + } + + } + + public static final class AttributeMappingBuilder { + + private String from; + private String to; + private String filter; + private String filterBaseDn; + private String extractRdn; + private Boolean searchRecursive; + private Integer roleRecursion; + private String roleRecursionName; + private String reference; + + public AttributeMappingBuilder from(String from) { + this.from = from; + return this; + } + + public AttributeMappingBuilder to(String to) { + this.to = to; + return this; + } + + public AttributeMappingBuilder filter(String filter) { + this.filter = filter; + return this; + } + + public AttributeMappingBuilder filterBaseDn(String filterBaseDn) { + this.filterBaseDn = filterBaseDn; + return this; + } + + public AttributeMappingBuilder extractRdn(String extractRdn) { + this.extractRdn = extractRdn; + return this; + } + + public AttributeMappingBuilder searchRecursive(Boolean searchRecursive) { + this.searchRecursive = searchRecursive; + return this; + } + + public AttributeMappingBuilder roleRecursion(Integer roleRecursion) { + this.roleRecursion = roleRecursion; + return this; + } + + public AttributeMappingBuilder roleRecursionName(String roleRecursionName) { + this.roleRecursionName = roleRecursionName; + return this; + } + + public AttributeMappingBuilder reference(String reference) { + this.reference = reference; + return this; + } + + public AttributeMapping build() { + return new AttributeMapping(this); + } + + } + + public static final class UserPasswordMapper { + + private final String from; + private final Boolean writable; + private final Boolean verifiable; + + private UserPasswordMapper(UserPasswordMapperBuilder builder) { + this.from = builder.from; + this.writable = builder.writable; + this.verifiable = builder.verifiable; + } + + public String getFrom() { + return from; + } + + public Boolean getWritable() { + return writable; + } + + public Boolean getVerifiable() { + return verifiable; + } + + } + + public static final class UserPasswordMapperBuilder { + + private String from; + private Boolean writable; + private Boolean verifiable; + + public UserPasswordMapperBuilder from(String from) { + this.from = from; + return this; + } + + public UserPasswordMapperBuilder writable(Boolean writable) { + this.writable = writable; + return this; + } + + public UserPasswordMapperBuilder verifiable(Boolean verifiable) { + this.verifiable = verifiable; + return this; + } + + public UserPasswordMapper build() { + if (from == null || from.isEmpty()) { + throw new IllegalArgumentException("identity-mapping.user-password-mapper.from must not be null and must have a minimum length of 1 characters"); + } + return new UserPasswordMapper(this); + } + } + + public static final class OtpCredentialMapper { + + private final String algorithmFrom; + private final String hashFrom; + private final String seedFrom; + private final String sequenceFrom; + + private OtpCredentialMapper(OtpCredentialMapperBuilder builder) { + this.algorithmFrom = builder.algorithmFrom; + this.hashFrom = builder.hashFrom; + this.seedFrom = builder.seedFrom; + this.sequenceFrom = builder.sequenceFrom; + } + + public String getAlgorithmFrom() { + return algorithmFrom; + } + + public String getHashFrom() { + return hashFrom; + } + + public String getSeedFrom() { + return seedFrom; + } + + public String getSequenceFrom() { + return sequenceFrom; + } + + } + + public static final class OtpCredentialMapperBuilder { + + private String algorithmFrom; + private String hashFrom; + private String seedFrom; + private String sequenceFrom; + + public OtpCredentialMapperBuilder algorithmFrom(String algorithmFrom) { + this.algorithmFrom = algorithmFrom; + return this; + } + + public OtpCredentialMapperBuilder hashFrom(String hashFrom) { + this.hashFrom = hashFrom; + return this; + } + + public OtpCredentialMapperBuilder seedFrom(String seedFrom) { + this.seedFrom = seedFrom; + return this; + } + + public OtpCredentialMapperBuilder sequenceFrom(String sequenceFrom) { + this.sequenceFrom = sequenceFrom; + return this; + } + + public OtpCredentialMapper build() { + if (algorithmFrom == null || algorithmFrom.isEmpty()) { + throw new IllegalArgumentException("identity-mapping.otp-credential-mapper.algorithm-from must not be null and must have a minimum length of 1 characters"); + } + if (hashFrom == null || hashFrom.isEmpty()) { + throw new IllegalArgumentException("identity-mapping.otp-credential-mapper.hash-from must not be null and must have a minimum length of 1 characters"); + } + if (seedFrom == null || seedFrom.isEmpty()) { + throw new IllegalArgumentException("identity-mapping.otp-credential-mapper.seed-from must not be null and must have a minimum length of 1 characters"); + } + if (sequenceFrom == null || sequenceFrom.isEmpty()) { + throw new IllegalArgumentException("identity-mapping.otp-credential-mapper.sequence-from must not be null and must have a minimum length of 1 characters"); + } + return new OtpCredentialMapper(this); + } + } + + public static final class X509CredentialMapper { + + private final String digestFrom; + private final String digestAlgorithm; + private final String certificateFrom; + private final String serialNumberFrom; + private final String subjectDnFrom; + + private X509CredentialMapper(X509CredentialMapperBuilder builder) { + this.digestFrom = builder.digestFrom; + this.digestAlgorithm = builder.digestAlgorithm; + this.certificateFrom = builder.certificateFrom; + this.serialNumberFrom = builder.serialNumberFrom; + this.subjectDnFrom = builder.subjectDnFrom; + } + + public String getDigestFrom() { + return digestFrom; + } + + public String getDigestAlgorithm() { + return digestAlgorithm; + } + + public String getCertificateFrom() { + return certificateFrom; + } + + public String getSerialNumberFrom() { + return serialNumberFrom; + } + + public String getSubjectDnFrom() { + return subjectDnFrom; + } + + } + + public static final class X509CredentialMapperBuilder { + + private String digestFrom; + private String digestAlgorithm; + private String certificateFrom; + private String serialNumberFrom; + private String subjectDnFrom; + + public X509CredentialMapperBuilder digestFrom(String digestFrom) { + this.digestFrom = digestFrom; + return this; + } + + public X509CredentialMapperBuilder digestAlgorithm(String digestAlgorithm) { + this.digestAlgorithm = digestAlgorithm; + return this; + } + + public X509CredentialMapperBuilder certificateFrom(String certificateFrom) { + this.certificateFrom = certificateFrom; + return this; + } + + public X509CredentialMapperBuilder serialNumberFrom(String serialNumberFrom) { + this.serialNumberFrom = serialNumberFrom; + return this; + } + + public X509CredentialMapperBuilder subjectDnFrom(String subjectDnFrom) { + this.subjectDnFrom = subjectDnFrom; + return this; + } + + public X509CredentialMapper build() { + return new X509CredentialMapper(this); + } + } + + public static final class NewIdentityAttributes { + + private final String name; + private List values; + + private NewIdentityAttributes(NewIdentityAttributesBuilder builder) { + this.name = builder.name; + this.values = builder.values; + } + + public String getName() { + return name; + } + + public List getValues() { + return values; + } + + } + + public static final class NewIdentityAttributesBuilder { + + private String name; + private List values = new ArrayList(); + + public NewIdentityAttributesBuilder name(String name) { + this.name = name; + return this; + } + + public NewIdentityAttributesBuilder addValues(String... values) { + if (values == null) { + throw new IllegalArgumentException("Values added to NewIdentityAttributesBuilder for ldap-realm must not be null"); + } + Collections.addAll(this.values, values); + return this; + } + + public NewIdentityAttributes build() { + if (name == null || name.isEmpty()) { + throw new IllegalArgumentException("name must not be null and must have a minimum length of 1 characters"); + } + if (values == null || values.isEmpty()) { + throw new IllegalArgumentException("values must not be null and must include at least one entry"); + } + return new NewIdentityAttributes(this); + } + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddPropertiesRealm.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddPropertiesRealm.java new file mode 100644 index 00000000..be11866c --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddPropertiesRealm.java @@ -0,0 +1,142 @@ +package org.wildfly.extras.creaper.commands.elytron.realm; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddPropertiesRealm implements OnlineCommand { + + private static final String REALM_TYPE = "properties-realm"; + + private final String name; + private final String groupsAttribute; + private final Boolean plainText; + private final String digestRealmName; + private final String userProperiesPath; + private final String userPropertiesRelativeTo; + private final String groupsProperiesPath; + private final String groupsPropertiesRelativeTo; + private final boolean replaceExisting; + + private AddPropertiesRealm(Builder builder) { + this.name = builder.name; + this.groupsAttribute = builder.groupsAttribute; + this.plainText = builder.plainText; + this.digestRealmName = builder.digestRealmName; + this.userProperiesPath = builder.userProperiesPath; + this.userPropertiesRelativeTo = builder.userPropertiesRelativeTo; + this.groupsProperiesPath = builder.groupsProperiesPath; + this.groupsPropertiesRelativeTo = builder.groupsPropertiesRelativeTo; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address securityRealmAddress = Address.subsystem("elytron").and(REALM_TYPE, name); + if (replaceExisting) { + ops.removeIfExists(securityRealmAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + Values groupsProperties = groupsProperiesPath != null + ? Values.empty() + .and("path", groupsProperiesPath) + .andOptional("relative-to", groupsPropertiesRelativeTo) + : null; + + ops.add(securityRealmAddress, Values.empty() + .andOptional("groups-attribute", groupsAttribute) + .andObject("users-properties", Values.empty() + .and("path", userProperiesPath) + .andOptional("relative-to", userPropertiesRelativeTo) + .andOptional("plain-text", plainText) + .andOptional("digest-realm-name", digestRealmName)) + .andObjectOptional("groups-properties", groupsProperties)); + + new Administration(ctx.client).reloadIfRequired(); + } + + public static final class Builder { + + private final String name; + private String groupsAttribute; + private Boolean plainText; + private String digestRealmName; + private String userProperiesPath; + private String userPropertiesRelativeTo; + private String groupsProperiesPath; + private String groupsPropertiesRelativeTo; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the properties-realm must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the properties-realm must not be empty value"); + } + this.name = name; + } + + public Builder groupsAttribute(String groupsAttribute) { + this.groupsAttribute = groupsAttribute; + return this; + } + + public Builder plainText(Boolean plainText) { + this.plainText = plainText; + return this; + } + + public Builder digestRealmName(String digestRealmName) { + this.digestRealmName = digestRealmName; + return this; + } + + public Builder userProperiesPath(String userProperiesPath) { + this.userProperiesPath = userProperiesPath; + return this; + } + + public Builder userPropertiesRelativeTo(String userPropertiesRelativeTo) { + this.userPropertiesRelativeTo = userPropertiesRelativeTo; + return this; + } + + public Builder groupsProperiesPath(String groupsProperiesPath) { + this.groupsProperiesPath = groupsProperiesPath; + return this; + } + + public Builder groupsPropertiesRelativeTo(String groupsPropertiesRelativeTo) { + this.groupsPropertiesRelativeTo = groupsPropertiesRelativeTo; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddPropertiesRealm build() { + if (userProperiesPath == null || userProperiesPath.isEmpty()) { + throw new IllegalArgumentException("Path to users-properties must not be null and must have a minimum length of 1 characters"); + } + if ((groupsProperiesPath == null || groupsProperiesPath.isEmpty()) + && groupsPropertiesRelativeTo != null) { + throw new IllegalArgumentException("relative-to for groups-properties can be set only if path is specified"); + } + return new AddPropertiesRealm(this); + } + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddTokenRealm.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddTokenRealm.java new file mode 100644 index 00000000..280907ee --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/realm/AddTokenRealm.java @@ -0,0 +1,309 @@ +package org.wildfly.extras.creaper.commands.elytron.realm; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.wildfly.extras.creaper.core.ServerVersion; + +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddTokenRealm implements OnlineCommand { + + private final String name; + private final Jwt jwt; + private final Oauth2Introspection oauth2Introspection; + private final String principalClaim; + private final boolean replaceExisting; + + private AddTokenRealm(Builder builder) { + this.name = builder.name; + this.principalClaim = builder.principalClaim; + this.jwt = builder.jwt; + this.oauth2Introspection = builder.oauth2Introspection; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address tokenRealmAddress = Address.subsystem("elytron") + .and("token-realm", name); + if (replaceExisting) { + ops.removeIfExists(tokenRealmAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + Values jwtProperties = jwt != null + ? Values.empty() + .andListOptional(String.class, "issuer", jwt.getIssuer()) + .andListOptional(String.class, "audience", jwt.getAudience()) + .andOptional("public-key", jwt.getPublicKey()) + .andOptional("key-store", jwt.getKeyStore()) + .andOptional("certificate", jwt.getCertificate()) + : null; + + Values oauth2IntrospectionProperties = oauth2Introspection != null + ? Values.empty() + .and("client-id", oauth2Introspection.getClientId()) + .and("client-secret", oauth2Introspection.getClientSecret()) + .and("introspection-url", oauth2Introspection.getIntrospectionUrl()) + .andOptional("client-ssl-context", oauth2Introspection.getClientSslContext()) + .andOptional("host-name-verification-policy", oauth2Introspection.getHostNameVerificationPolicy()) + : null; + + ops.add(tokenRealmAddress, Values.empty() + .andOptional("principal-claim", principalClaim) + .andObjectOptional("jwt", jwtProperties) + .andObjectOptional("oauth2-introspection", oauth2IntrospectionProperties)); + } + + public static final class Builder { + + private final String name; + private Jwt jwt; + private Oauth2Introspection oauth2Introspection; + private String principalClaim; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the token-realm must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the token-realm must not be empty value"); + } + this.name = name; + } + + public Builder jwt(Jwt jwt) { + if (jwt == null) { + throw new IllegalArgumentException("Jwt added to token-realm must not be null"); + } + this.jwt = jwt; + return this; + } + + public Builder oauth2Introspection(Oauth2Introspection oauth2Introspection) { + if (oauth2Introspection == null) { + throw new IllegalArgumentException("OAuth2-introspection added to token-realm must not be null"); + } + this.oauth2Introspection = oauth2Introspection; + return this; + } + + public Builder principalClaim(String principalClaim) { + if (principalClaim == null || principalClaim.isEmpty()) { + throw new IllegalArgumentException("Principal-claim must not be null and must have a minimum length of 1 character"); + } + this.principalClaim = principalClaim; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddTokenRealm build() { + if (jwt == null && oauth2Introspection == null) { + throw new IllegalArgumentException("Jwt or oauth2-introspection must not be null"); + } + if (jwt != null && oauth2Introspection != null) { + throw new IllegalArgumentException("It is not possible to define both jwt and oauth2-introspection"); + } + + return new AddTokenRealm(this); + } + } + + public static final class Jwt { + + private final List issuer; + private final List audience; + private final String publicKey; + private final String keyStore; + private final String certificate; + + private Jwt(JwtBuilder builder) { + this.issuer = builder.issuer; + this.audience = builder.audience; + this.publicKey = builder.publicKey; + this.keyStore = builder.keyStore; + this.certificate = builder.certificate; + } + + public List getIssuer() { + return issuer; + } + + public List getAudience() { + return audience; + } + + public String getPublicKey() { + return publicKey; + } + + public String getKeyStore() { + return keyStore; + } + + public String getCertificate() { + return certificate; + } + + } + + public static final class JwtBuilder { + + private List issuer; + private List audience; + private String publicKey; + private String keyStore; + private String certificate; + + public JwtBuilder addIssuer(String... issuer) { + if (issuer == null) { + throw new IllegalArgumentException("Issuer added to token-realm must not be null"); + } + if (this.issuer == null) { + this.issuer = new ArrayList(); + } + Collections.addAll(this.issuer, issuer); + return this; + } + + public JwtBuilder addAudience(String... audience) { + if (audience == null) { + throw new IllegalArgumentException("Audience added to token-realm must not be null"); + } + + if (this.audience == null) { + this.audience = new ArrayList(); + } + + Collections.addAll(this.audience, audience); + return this; + } + + public JwtBuilder publicKey(String publicKey) { + this.publicKey = publicKey; + return this; + } + + public JwtBuilder keyStore(String keyStore) { + this.keyStore = keyStore; + return this; + } + + public JwtBuilder certificate(String certificate) { + this.certificate = certificate; + return this; + } + + public Jwt build() { + return new Jwt(this); + } + } + + public static final class Oauth2Introspection { + + private final String clientId; + private final String clientSecret; + private final String introspectionUrl; + private final String clientSslContext; + private final String hostNameVerificationPolicy; + + private Oauth2Introspection(Oauth2IntrospectionBuilder builder) { + this.clientId = builder.clientId; + this.clientSecret = builder.clientSecret; + this.introspectionUrl = builder.introspectionUrl; + this.clientSslContext = builder.clientSslContext; + this.hostNameVerificationPolicy = builder.hostNameVerificationPolicy; + } + + public String getClientId() { + return clientId; + } + + public String getClientSecret() { + return clientSecret; + } + + public String getIntrospectionUrl() { + return introspectionUrl; + } + + public String getClientSslContext() { + return clientSslContext; + } + + public String getHostNameVerificationPolicy() { + return hostNameVerificationPolicy; + } + + } + + public static final class Oauth2IntrospectionBuilder { + + private String clientId; + private String clientSecret; + private String introspectionUrl; + private String clientSslContext; + private String hostNameVerificationPolicy; + + public Oauth2IntrospectionBuilder clientId(String clientId) { + this.clientId = clientId; + return this; + } + + public Oauth2IntrospectionBuilder clientSecret(String clientSecret) { + this.clientSecret = clientSecret; + return this; + } + + public Oauth2IntrospectionBuilder introspectionUrl(String introspectionUrl) { + this.introspectionUrl = introspectionUrl; + return this; + } + + public Oauth2IntrospectionBuilder clientSslContext(String clientSslContext) { + if (clientSslContext == null || clientSslContext.isEmpty()) { + throw new IllegalArgumentException("Client-ssl-context added to token-realm must not be null and must have a minimum length of 1 character"); + } + this.clientSslContext = clientSslContext; + return this; + } + + public Oauth2IntrospectionBuilder hostNameVerificationPolicy(String hostNameVerificationPolicy) { + if (hostNameVerificationPolicy == null || hostNameVerificationPolicy.isEmpty()) { + throw new IllegalArgumentException("Host-name-verification-policy added to token-realm must not be null and must have a minimum length of 1 character"); + } + this.hostNameVerificationPolicy = hostNameVerificationPolicy; + return this; + } + + public Oauth2Introspection build() { + if (clientId == null || clientId.isEmpty()) { + throw new IllegalArgumentException("Client-id must not be null and must have a minimum length of 1 character"); + } + if (clientSecret == null || clientSecret.isEmpty()) { + throw new IllegalArgumentException("Client-secret must not be null and must have at least 1 entry"); + } + if (introspectionUrl == null || introspectionUrl.isEmpty()) { + throw new IllegalArgumentException("Introspection-url must not be null and must have a minimum length of 1 character"); + } + + return new Oauth2Introspection(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddAggregateSaslServerFactory.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddAggregateSaslServerFactory.java new file mode 100644 index 00000000..749dfc05 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddAggregateSaslServerFactory.java @@ -0,0 +1,81 @@ +package org.wildfly.extras.creaper.commands.elytron.sasl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddAggregateSaslServerFactory implements OnlineCommand { + + private final String name; + private final List saslServerFactories; + private final boolean replaceExisting; + + private AddAggregateSaslServerFactory(Builder builder) { + this.name = builder.name; + this.saslServerFactories = builder.saslServerFactories; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address factoryAddress = Address.subsystem("elytron") + .and("aggregate-sasl-server-factory", name); + if (replaceExisting) { + ops.removeIfExists(factoryAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(factoryAddress, Values.empty() + .andList(String.class, "sasl-server-factories", saslServerFactories)); + } + + public static final class Builder { + + private final String name; + private List saslServerFactories = new ArrayList(); + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the aggregate-sasl-server-factory must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the aggregate-sasl-server-factory must not be empty value"); + } + this.name = name; + } + + public Builder addSaslServerFactories(String... saslServerFactories) { + if (saslServerFactories == null) { + throw new IllegalArgumentException("sasl-server-factories added to aggregate-sasl-server-factory must not be null"); + } + Collections.addAll(this.saslServerFactories, saslServerFactories); + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddAggregateSaslServerFactory build() { + if (saslServerFactories == null || saslServerFactories.size() < 2) { + throw new IllegalArgumentException("sasl-server-factory must not be null and must include at least two entries"); + } + return new AddAggregateSaslServerFactory(this); + } + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddConfigurableSaslServerFactory.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddConfigurableSaslServerFactory.java new file mode 100644 index 00000000..68c1366b --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddConfigurableSaslServerFactory.java @@ -0,0 +1,212 @@ +package org.wildfly.extras.creaper.commands.elytron.sasl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.jboss.dmr.ModelNode; +import org.wildfly.extras.creaper.commands.elytron.Property; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddConfigurableSaslServerFactory implements OnlineCommand { + + private final String name; + private final String saslServerFactory; + private final String protocol; + private final String serverName; + private final List filters; + private final List properties; + private final boolean replaceExisting; + + private AddConfigurableSaslServerFactory(Builder builder) { + this.name = builder.name; + this.saslServerFactory = builder.saslServerFactory; + this.protocol = builder.protocol; + this.serverName = builder.serverName; + this.filters = builder.filters; + this.properties = builder.properties; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address factoryAddress = Address.subsystem("elytron") + .and("configurable-sasl-server-factory", name); + if (replaceExisting) { + ops.removeIfExists(factoryAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + List filterNodeList = null; + if (filters != null && !filters.isEmpty()) { + filterNodeList = new ArrayList(); + for (Filter filter : filters) { + ModelNode filterNode = new ModelNode(); + if (filter.getPatternFilter() != null) { + filterNode.add("pattern-filter", filter.getPatternFilter()); + } + if (filter.getPredefinedFilter() != null) { + filterNode.add("predefined-filter", filter.getPredefinedFilter()); + } + if (filter.getEnabling() != null) { + filterNode.add("enabling", filter.getEnabling()); + } + filterNode = filterNode.asObject(); + filterNodeList.add(filterNode); + } + } + + ModelNode propertyNode = null; + if (properties != null && !properties.isEmpty()) { + propertyNode = new ModelNode(); + for (Property property : properties) { + propertyNode.add(property.getKey(), property.getValue()); + } + propertyNode = propertyNode.asObject(); + } + + ops.add(factoryAddress, Values.empty() + .and("sasl-server-factory", saslServerFactory) + .andOptional("protocol", protocol) + .andOptional("server-name", serverName) + .andListOptional(ModelNode.class, "filters", filterNodeList) + .andOptional("properties", propertyNode)); + + } + + public static final class Builder { + + private final String name; + private String saslServerFactory; + private String protocol; + private String serverName; + private List filters = new ArrayList(); + private List properties = new ArrayList(); + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the configurable-sasl-server-factory must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the configurable-sasl-server-factory must not be empty value"); + } + this.name = name; + } + + public Builder saslServerFactory(String saslServerFactory) { + this.saslServerFactory = saslServerFactory; + return this; + } + + public Builder protocol(String protocol) { + this.protocol = protocol; + return this; + } + + public Builder serverName(String serverName) { + this.serverName = serverName; + return this; + } + + public Builder addFilters(Filter... filters) { + if (filters == null) { + throw new IllegalArgumentException("Filters added to configurable-sasl-server-factory must not be null"); + } + Collections.addAll(this.filters, filters); + return this; + } + + public Builder addProperties(Property... properties) { + if (properties == null) { + throw new IllegalArgumentException("Properties added to configurable-sasl-server-factory must not be null"); + } + Collections.addAll(this.properties, properties); + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddConfigurableSaslServerFactory build() { + if (saslServerFactory == null || saslServerFactory.isEmpty()) { + throw new IllegalArgumentException("sasl-server-factory must not be null and must include at least one entry"); + } + return new AddConfigurableSaslServerFactory(this); + } + + } + + public static final class Filter { + + private final String patternFilter; + private final String predefinedFilter; + private final Boolean enabling; + + private Filter(FilterBuilder builder) { + this.patternFilter = builder.patternFilter; + this.predefinedFilter = builder.predefinedFilter; + this.enabling = builder.enabling; + } + + public String getPatternFilter() { + return patternFilter; + } + + public String getPredefinedFilter() { + return predefinedFilter; + } + + public Boolean getEnabling() { + return enabling; + } + + } + + public static final class FilterBuilder { + + private String patternFilter; + private String predefinedFilter; + private Boolean enabling; + + public FilterBuilder patternFilter(String patternFilter) { + this.patternFilter = patternFilter; + return this; + } + + public FilterBuilder predefinedFilter(String predefinedFilter) { + this.predefinedFilter = predefinedFilter; + return this; + } + + public FilterBuilder enabling(Boolean enabling) { + this.enabling = enabling; + return this; + } + + public Filter build() { + if ((patternFilter == null || patternFilter.isEmpty()) + && (predefinedFilter == null || predefinedFilter.isEmpty())) { + throw new IllegalArgumentException("pattern-filter or predefined-filter must not be null or empty"); + } + if (patternFilter != null && predefinedFilter != null) { + throw new IllegalArgumentException("both pattern-filter and predefined-filter cannot be used"); + } + return new Filter(this); + } + + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddMechanismProviderFilteringSaslServerFactory.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddMechanismProviderFilteringSaslServerFactory.java new file mode 100644 index 00000000..7ee020aa --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddMechanismProviderFilteringSaslServerFactory.java @@ -0,0 +1,204 @@ +package org.wildfly.extras.creaper.commands.elytron.sasl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.jboss.dmr.ModelNode; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddMechanismProviderFilteringSaslServerFactory implements OnlineCommand { + + private final String name; + private final String saslServerFactory; + private final Boolean enabling; + private final List filters; + private final boolean replaceExisting; + + private AddMechanismProviderFilteringSaslServerFactory(Builder builder) { + this.name = builder.name; + this.saslServerFactory = builder.saslServerFactory; + this.enabling = builder.enabling; + this.filters = builder.filters; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + Operations ops = new Operations(ctx.client); + Address factoryAddress = Address.subsystem("elytron") + .and("mechanism-provider-filtering-sasl-server-factory", name); + if (replaceExisting) { + ops.removeIfExists(factoryAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + List filtersNodeList = null; + if (filters != null && !filters.isEmpty()) { + filtersNodeList = new ArrayList(); + for (Filter filter : filters) { + ModelNode filterModelNode = new ModelNode(); + filterModelNode.add("provider-name", filter.getProviderName()); + if (filter.getMechanismName() != null && !filter.getMechanismName().isEmpty()) { + filterModelNode.add("mechanism-name", filter.getMechanismName()); + } + if (filter.getProviderVersion() != null) { + filterModelNode.add("provider-version", filter.getProviderVersion()); + } + if (filter.getVersionComparison() != null) { + filterModelNode.add("version-comparison", + filter.getVersionComparison().getVersionComparisonName()); + } + filterModelNode = filterModelNode.asObject(); + filtersNodeList.add(filterModelNode); + } + } + + ops.add(factoryAddress, Values.empty() + .and("sasl-server-factory", saslServerFactory) + .andOptional("enabling", enabling) + .andListOptional(ModelNode.class, "filters", filtersNodeList)); + } + + public static final class Builder { + + private final String name; + private String saslServerFactory; + private Boolean enabling; + private List filters = new ArrayList(); + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the mechanism-provider-filtering-sasl-server-factory must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the mechanism-provider-filtering-sasl-server-factory must not be empty value"); + } + this.name = name; + } + + public Builder saslServerFactory(String saslServerFactory) { + this.saslServerFactory = saslServerFactory; + return this; + } + + public Builder enabling(Boolean enabling) { + this.enabling = enabling; + return this; + } + + public Builder addFilters(Filter... filters) { + if (filters == null) { + throw new IllegalArgumentException("Filter added to filters must not be null"); + } + Collections.addAll(this.filters, filters); + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddMechanismProviderFilteringSaslServerFactory build() { + if (saslServerFactory == null || saslServerFactory.isEmpty()) { + throw new IllegalArgumentException("sasl-server-factory must not be null and must include at least one entry"); + } + return new AddMechanismProviderFilteringSaslServerFactory(this); + } + + } + + public static final class Filter { + + private final String mechanismName; + private final String providerName; + private final Double providerVersion; + private final VersionComparison versionComparison; + + private Filter(FilterBuilder builder) { + this.mechanismName = builder.mechanismName; + this.providerName = builder.providerName; + this.providerVersion = builder.providerVersion; + this.versionComparison = builder.versionComparison; + } + + public String getMechanismName() { + return mechanismName; + } + + public String getProviderName() { + return providerName; + } + + public Double getProviderVersion() { + return providerVersion; + } + + public VersionComparison getVersionComparison() { + return versionComparison; + } + + } + + public static final class FilterBuilder { + + private String mechanismName; + private String providerName; + private Double providerVersion; + private VersionComparison versionComparison; + + public FilterBuilder mechanismName(String mechanismName) { + this.mechanismName = mechanismName; + return this; + } + + public FilterBuilder providerName(String providerName) { + this.providerName = providerName; + return this; + } + + public FilterBuilder providerVersion(Double providerVersion) { + this.providerVersion = providerVersion; + return this; + } + + public FilterBuilder versionComparison(VersionComparison versionComparison) { + this.versionComparison = versionComparison; + return this; + } + + public Filter build() { + if (providerName == null || providerName.isEmpty()) { + throw new IllegalArgumentException("provider-name must not be null or empty"); + } + return new Filter(this); + } + + } + + public static enum VersionComparison { + + GREATER_THAN("greater-than"), LESS_THAN("less-than"); + + private final String versionComparisonName; + + private VersionComparison(String versionComparisonName) { + this.versionComparisonName = versionComparisonName; + } + + public String getVersionComparisonName() { + return versionComparisonName; + } + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddProviderSaslServerFactory.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddProviderSaslServerFactory.java new file mode 100644 index 00000000..df737af0 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddProviderSaslServerFactory.java @@ -0,0 +1,73 @@ +package org.wildfly.extras.creaper.commands.elytron.sasl; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddProviderSaslServerFactory implements OnlineCommand { + + private final String name; + private final String providers; + private final boolean replaceExisting; + + private AddProviderSaslServerFactory(Builder builder) { + this.name = builder.name; + this.providers = builder.providers; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address factoryAddress = Address.subsystem("elytron") + .and("provider-sasl-server-factory", name); + if (replaceExisting) { + ops.removeIfExists(factoryAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(factoryAddress, Values.empty() + .andOptional("providers", providers)); + } + + public static final class Builder { + + private final String name; + private String providers; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the provider-sasl-server-factory must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the provider-sasl-server-factory must not be empty value"); + } + this.name = name; + } + + public Builder providers(String providers) { + this.providers = providers; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddProviderSaslServerFactory build() { + return new AddProviderSaslServerFactory(this); + } + + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddSaslAuthenticationFactory.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddSaslAuthenticationFactory.java new file mode 100644 index 00000000..a6463174 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddSaslAuthenticationFactory.java @@ -0,0 +1,158 @@ +package org.wildfly.extras.creaper.commands.elytron.sasl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.jboss.dmr.ModelNode; +import org.wildfly.extras.creaper.commands.elytron.Mechanism; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddSaslAuthenticationFactory implements OnlineCommand { + + private final String name; + private final String securityDomain; + private final String saslServerFactory; + private final List mechanismConfigurations; + private final boolean replaceExisting; + + private AddSaslAuthenticationFactory(Builder builder) { + this.name = builder.name; + this.securityDomain = builder.securityDomain; + this.saslServerFactory = builder.saslServerFactory; + this.mechanismConfigurations = builder.mechanismConfigurations; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address factoryAddress = Address.subsystem("elytron") + .and("sasl-authentication-factory", name); + if (replaceExisting) { + ops.removeIfExists(factoryAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + List mechanismConfigurationsNodeList = null; + if (mechanismConfigurations != null && !mechanismConfigurations.isEmpty()) { + mechanismConfigurationsNodeList = new ArrayList(); + for (Mechanism mechanismConfiguration : mechanismConfigurations) { + ModelNode mechanismNode = new ModelNode(); + addOptionalToModelNode(mechanismNode, "mechanism-name", mechanismConfiguration.getMechanismName()); + addOptionalToModelNode(mechanismNode, "host-name", mechanismConfiguration.getHostName()); + addOptionalToModelNode(mechanismNode, "protocol", mechanismConfiguration.getProtocol()); + addOptionalToModelNode(mechanismNode, "pre-realm-principal-transformer", + mechanismConfiguration.getPreRealmPrincipalTransformer()); + addOptionalToModelNode(mechanismNode, "post-realm-principal-transformer", + mechanismConfiguration.getPostRealmPrincipalTransformer()); + addOptionalToModelNode(mechanismNode, "final-principal-transformer", + mechanismConfiguration.getFinalPrincipalTransformer()); + addOptionalToModelNode(mechanismNode, "realm-mapper", mechanismConfiguration.getRealmMapper()); + addOptionalToModelNode(mechanismNode, "credential-security-factory", + mechanismConfiguration.getCredentialSecurityFactory()); + + List mechanismRealmConfigurationsNodeList = null; + if (mechanismConfiguration.getMechanismRealmConfigurations() != null + && !mechanismConfiguration.getMechanismRealmConfigurations().isEmpty()) { + + mechanismRealmConfigurationsNodeList = new ArrayList(); + for (Mechanism.MechanismRealm mechanismRealm + : mechanismConfiguration.getMechanismRealmConfigurations()) { + ModelNode mechanismRealmNode = new ModelNode(); + mechanismRealmNode.add("realm-name", mechanismRealm.getRealmName()); + addOptionalToModelNode(mechanismRealmNode, "pre-realm-principal-transformer", + mechanismRealm.getPreRealmPrincipalTransformer()); + addOptionalToModelNode(mechanismRealmNode, "post-realm-principal-transformer", + mechanismRealm.getPostRealmPrincipalTransformer()); + addOptionalToModelNode(mechanismRealmNode, "final-principal-transformer", + mechanismRealm.getFinalPrincipalTransformer()); + addOptionalToModelNode(mechanismRealmNode, "realm-mapper", mechanismRealm.getRealmMapper()); + mechanismRealmNode = mechanismRealmNode.asObject(); + mechanismRealmConfigurationsNodeList.add(mechanismRealmNode); + } + ModelNode mechanismRealmConfigurations = new ModelNode(); + mechanismRealmConfigurations.set(mechanismRealmConfigurationsNodeList); + mechanismNode.add("mechanism-realm-configurations", mechanismRealmConfigurations); + } + + mechanismNode = mechanismNode.asObject(); + mechanismConfigurationsNodeList.add(mechanismNode); + } + } + + ops.add(factoryAddress, Values.empty() + .and("security-domain", securityDomain) + .and("sasl-server-factory", saslServerFactory) + .andListOptional(ModelNode.class, "mechanism-configurations", mechanismConfigurationsNodeList)); + + } + + private void addOptionalToModelNode(ModelNode node, String name, String value) { + if (value != null && !value.isEmpty()) { + node.add(name, value); + } + } + + public static final class Builder { + + private final String name; + private String securityDomain; + private String saslServerFactory; + private List mechanismConfigurations = new ArrayList(); + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the sasl-authentication-factory must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the sasl-authentication-factory must not be empty value"); + } + this.name = name; + } + + public Builder securityDomain(String securityDomain) { + this.securityDomain = securityDomain; + return this; + } + + public Builder saslServerFactory(String saslServerFactory) { + this.saslServerFactory = saslServerFactory; + return this; + } + + public Builder addMechanismConfigurations(Mechanism... mechanismConfigurations) { + if (mechanismConfigurations == null) { + throw new IllegalArgumentException("Mechanism added to mechanism-configuration must not be null"); + } + Collections.addAll(this.mechanismConfigurations, mechanismConfigurations); + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddSaslAuthenticationFactory build() { + if (securityDomain == null || securityDomain.isEmpty()) { + throw new IllegalArgumentException("security-domain must not be null and must have a minimum length of 1 characters"); + } + if (saslServerFactory == null || saslServerFactory.isEmpty()) { + throw new IllegalArgumentException("sasl-server-factory must not be null and must have a minimum length of 1 characters"); + } + return new AddSaslAuthenticationFactory(this); + } + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddServiceLoaderSaslServerFactory.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddServiceLoaderSaslServerFactory.java new file mode 100644 index 00000000..218ea07c --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddServiceLoaderSaslServerFactory.java @@ -0,0 +1,73 @@ +package org.wildfly.extras.creaper.commands.elytron.sasl; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddServiceLoaderSaslServerFactory implements OnlineCommand { + + private final String name; + private final String module; + private final boolean replaceExisting; + + private AddServiceLoaderSaslServerFactory(Builder builder) { + this.name = builder.name; + this.module = builder.module; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address factoryAddress = Address.subsystem("elytron") + .and("service-loader-sasl-server-factory", name); + if (replaceExisting) { + ops.removeIfExists(factoryAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(factoryAddress, Values.empty() + .andOptional("module", module)); + } + + public static final class Builder { + + private final String name; + private String module; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the service-loader-sasl-server-factory must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the service-loader-sasl-server-factory must not be empty value"); + } + this.name = name; + } + + public Builder module(String module) { + this.module = module; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddServiceLoaderSaslServerFactory build() { + return new AddServiceLoaderSaslServerFactory(this); + } + + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/securityproperty/AddSecurityProperty.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/securityproperty/AddSecurityProperty.java new file mode 100644 index 00000000..707ce672 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/securityproperty/AddSecurityProperty.java @@ -0,0 +1,58 @@ +package org.wildfly.extras.creaper.commands.elytron.securityproperty; + +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; + +public final class AddSecurityProperty implements OnlineCommand { + + private final String key; + private final String value; + + private AddSecurityProperty(Builder builder) { + this.key = builder.key; + this.value = builder.value; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address securityPropertyAddress = Address.subsystem("elytron"); + ops.writeAttribute(securityPropertyAddress, "security-properties." + key, value); + } + + public static final class Builder { + + private final String key; + private String value; + + public Builder(String key) { + if (key == null) { + throw new IllegalArgumentException("Key of the security-property must be specified as non null value"); + } + if (key.isEmpty()) { + throw new IllegalArgumentException("Key of the security-property must not be empty value"); + } + this.key = key; + } + + public Builder value(String value) { + this.value = value; + return this; + } + + public AddSecurityProperty build() { + if (value == null || value.isEmpty()) { + throw new IllegalArgumentException("Value must not be null or empty"); + } + + return new AddSecurityProperty(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AbstractAddSSLContext.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AbstractAddSSLContext.java new file mode 100644 index 00000000..4e5d6fff --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AbstractAddSSLContext.java @@ -0,0 +1,104 @@ +package org.wildfly.extras.creaper.commands.elytron.tls; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import org.wildfly.extras.creaper.core.offline.OfflineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommand; + +abstract class AbstractAddSSLContext implements OnlineCommand, OfflineCommand { + + protected final String name; + protected final String cipherSuiteFilter; + protected final List protocols; + protected final String keyManager; + protected final String trustManager; + protected final String providers; + protected final String providerName; + protected final boolean replaceExisting; + + protected AbstractAddSSLContext(Builder builder) { + this.name = builder.name; + this.cipherSuiteFilter = builder.cipherSuiteFilter; + this.protocols = builder.protocols; + this.keyManager = builder.keyManager; + this.trustManager = builder.trustManager; + this.providers = builder.providers; + this.providerName = builder.providerName; + this.replaceExisting = builder.replaceExisting; + } + + protected String joinList(List list) { + if (list.isEmpty()) { + return ""; + } + Iterator iterator = list.iterator(); + StringBuilder sb = new StringBuilder(iterator.next()); + while (iterator.hasNext()) { + sb.append(" ").append(iterator.next()); + } + return sb.toString(); + } + + abstract static class Builder { + + protected final String name; + protected String cipherSuiteFilter; + protected List protocols; + protected String keyManager; + protected String trustManager; + private boolean replaceExisting; + protected String providers; + protected String providerName; + + public Builder(String name) { + if (name == null) { + throw new IllegalArgumentException("Name of the ssl-context must be specified as non null value"); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Name of the ssl-context must not be empty value"); + } + this.name = name; + } + + public final THIS protocols(String... protocols) { + if (protocols != null && protocols.length > 0) { + this.protocols = Arrays.asList(protocols); + } + return (THIS) this; + } + + public final THIS cipherSuiteFilter(String cipherSuiteFilter) { + this.cipherSuiteFilter = cipherSuiteFilter; + return (THIS) this; + } + + public final THIS keyManager(String keyManager) { + this.keyManager = keyManager; + return (THIS) this; + } + + public final THIS trustManager(String trustManager) { + this.trustManager = trustManager; + return (THIS) this; + } + + public final THIS replaceExisting() { + this.replaceExisting = true; + return (THIS) this; + } + + public final THIS providers(String providers) { + this.providers = providers; + return (THIS) this; + } + + public final THIS providerName(String providerName) { + this.providerName = providerName; + return (THIS) this; + } + + public abstract AbstractAddSSLContext build(); + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AddClientSSLContext.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AddClientSSLContext.java new file mode 100644 index 00000000..5bcb3434 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AddClientSSLContext.java @@ -0,0 +1,71 @@ +package org.wildfly.extras.creaper.commands.elytron.tls; + +import org.wildfly.extras.creaper.commands.foundation.offline.xml.GroovyXmlTransform; +import org.wildfly.extras.creaper.commands.foundation.offline.xml.Subtree; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.offline.OfflineCommandContext; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddClientSSLContext extends AbstractAddSSLContext { + + private AddClientSSLContext(Builder builder) { + super(builder); + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address clientSSLContextAddress = Address.subsystem("elytron").and("client-ssl-context", name); + if (replaceExisting) { + ops.removeIfExists(clientSSLContextAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(clientSSLContextAddress, Values.empty() + .andOptional("cipher-suite-filter", cipherSuiteFilter) + .andOptional("key-manager", keyManager) + .andOptional("trust-manager", trustManager) + .andListOptional(String.class, "protocols", protocols)); + } + + @Override + public void apply(OfflineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + ctx.client.apply(GroovyXmlTransform.of(AddClientSSLContext.class) + .subtree("elytronSubsystem", Subtree.subsystem("elytron")) + .parameter("atrName", name) + .parameter("atrCipherSuiteFilter", cipherSuiteFilter) + .parameter("atrKeyManager", keyManager) + .parameter("atrTrustManager", trustManager) + .parameter("atrProtocols", protocols != null ? joinList(protocols) : null) + .parameter("atrProviders", providers) + .parameter("atrProviderName", providerName) + .parameter("atrReplaceExisting", replaceExisting) + .build()); + } + + public static final class Builder extends AbstractAddSSLContext.Builder { + + public Builder(String name) { + super(name); + } + + @Override + public AddClientSSLContext build() { + return new AddClientSSLContext(this); + } + + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AddFilteringKeyStore.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AddFilteringKeyStore.java new file mode 100644 index 00000000..60138d02 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AddFilteringKeyStore.java @@ -0,0 +1,105 @@ +package org.wildfly.extras.creaper.commands.elytron.tls; + +import org.wildfly.extras.creaper.commands.foundation.offline.xml.GroovyXmlTransform; +import org.wildfly.extras.creaper.commands.foundation.offline.xml.Subtree; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.offline.OfflineCommand; +import org.wildfly.extras.creaper.core.offline.OfflineCommandContext; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddFilteringKeyStore implements OnlineCommand, OfflineCommand { + + private final String name; + private final String keyStore; + private final String aliasFilter; + private final boolean replaceExisting; + + private AddFilteringKeyStore(Builder builder) { + this.name = builder.name; + this.keyStore = builder.keyStore; + this.aliasFilter = builder.aliasFilter; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address filteringKeyStoreAddress = Address.subsystem("elytron").and("filtering-key-store", name); + if (replaceExisting) { + ops.removeIfExists(filteringKeyStoreAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(filteringKeyStoreAddress, Values.empty() + .and("name", name) + .and("alias-filter", aliasFilter) + .and("key-store", keyStore)); + } + + @Override + public void apply(OfflineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + ctx.client.apply(GroovyXmlTransform.of(AddFilteringKeyStore.class) + .subtree("elytronSubsystem", Subtree.subsystem("elytron")) + .parameter("atrName", name) + .parameter("atrAliasFilter", aliasFilter) + .parameter("atrKeyStore", keyStore) + .parameter("atrReplaceExisting", replaceExisting) + .build()); + } + + public static final class Builder { + + private final String name; + private String aliasFilter; + private String keyStore; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null || name.isEmpty()) { + throw new IllegalArgumentException("Name of the filtering-key-store must be specified as non empty value"); + } + this.name = name; + } + + public Builder keyStore(String keyStore) { + this.keyStore = keyStore; + return this; + } + + public Builder aliasFilter(String aliasFilter) { + this.aliasFilter = aliasFilter; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddFilteringKeyStore build() { + + if (keyStore == null || keyStore.isEmpty()) { + throw new IllegalArgumentException("Key store of the filtering-key-store must be specified as non empty value"); + } + if (aliasFilter == null || aliasFilter.isEmpty()) { + throw new IllegalArgumentException("Alias filter of the filtering-key-store must be specified as non empty value"); + } + + return new AddFilteringKeyStore(this); + } + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyManager.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyManager.java new file mode 100644 index 00000000..a32ac430 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyManager.java @@ -0,0 +1,143 @@ +package org.wildfly.extras.creaper.commands.elytron.tls; + +import org.wildfly.extras.creaper.commands.elytron.CredentialRef; +import org.wildfly.extras.creaper.commands.foundation.offline.xml.GroovyXmlTransform; +import org.wildfly.extras.creaper.commands.foundation.offline.xml.Subtree; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.offline.OfflineCommand; +import org.wildfly.extras.creaper.core.offline.OfflineCommandContext; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddKeyManager implements OnlineCommand, OfflineCommand { + + private final String name; + private final String algorithm; + private final String aliasFilter; + private final String keyStore; + private final CredentialRef credentialReference; + private final String providerName; + private final String providers; + private final boolean replaceExisting; + + private AddKeyManager(Builder builder) { + this.name = builder.name; + this.algorithm = builder.algorithm; + this.aliasFilter = builder.aliasFilter; + this.keyStore = builder.keyStore; + this.providerName = builder.providerName; + this.providers = builder.providers; + this.credentialReference = builder.credentialReference; + // Replace existing + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address keyManagerAddress = Address.subsystem("elytron").and("key-manager", name); + if (replaceExisting) { + ops.removeIfExists(keyManagerAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(keyManagerAddress, Values.empty() + .and("key-store", keyStore) + .andObject("credential-reference", credentialReference.toValues()) + .andOptional("algorithm", algorithm) + .andOptional("alias-filter", aliasFilter) + .andOptional("provider-name", providerName) + .andOptional("providers", providers)); + } + + @Override + public void apply(OfflineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + ctx.client.apply(GroovyXmlTransform.of(AddKeyManager.class) + .subtree("elytronSubsystem", Subtree.subsystem("elytron")) + .parameter("atrName", name) + .parameter("atrAlgorithm", algorithm) + .parameter("atrAliasFilter", aliasFilter) + .parameter("atrKeyStore", keyStore) + .parameters(credentialReference.toParameters()) + .parameter("atrProviderName", providerName) + .parameter("atrProviders", providers) + .parameter("atrReplaceExisting", replaceExisting) + .build()); + } + + public static final class Builder { + + private final String name; + private String algorithm; + private String aliasFilter; + private String keyStore; + private CredentialRef credentialReference; + private String providerName; + private String providers; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null || name.isEmpty()) { + throw new IllegalArgumentException("Name of the key-manager must be specified as non empty value"); + } + this.name = name; + } + + public Builder algorithm(String algorithm) { + this.algorithm = algorithm; + return this; + } + + public Builder aliasFilter(String aliasFilter) { + this.aliasFilter = aliasFilter; + return this; + } + + public Builder keyStore(String keyStore) { + this.keyStore = keyStore; + return this; + } + + public Builder providerName(String providerName) { + this.providerName = providerName; + return this; + } + + public Builder providers(String providers) { + this.providers = providers; + return this; + } + + public Builder credentialReference(CredentialRef credentialReference) { + this.credentialReference = credentialReference; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddKeyManager build() { + if (keyStore == null || keyStore.isEmpty()) { + throw new IllegalArgumentException("key-store must not be null and must include at least one entry"); + } + if (credentialReference == null) { + throw new IllegalArgumentException("Credential reference of the key-manager must be specified"); + } + return new AddKeyManager(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyStore.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyStore.java new file mode 100644 index 00000000..fe1ab348 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyStore.java @@ -0,0 +1,165 @@ +package org.wildfly.extras.creaper.commands.elytron.tls; + +import org.wildfly.extras.creaper.commands.elytron.CredentialRef; +import org.wildfly.extras.creaper.commands.foundation.offline.xml.GroovyXmlTransform; +import org.wildfly.extras.creaper.commands.foundation.offline.xml.Subtree; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.offline.OfflineCommand; +import org.wildfly.extras.creaper.core.offline.OfflineCommandContext; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddKeyStore implements OnlineCommand, OfflineCommand { + + private final String name; + private final String type; + private final String providerName; + private final String providers; + private final CredentialRef credentialReference; + private final String aliasFilter; + private final String path; + private final String relativeTo; + private final Boolean required; + private final boolean replaceExisting; + + private AddKeyStore(Builder builder) { + this.name = builder.name; + this.type = builder.type; + this.providerName = builder.providerName; + this.providers = builder.providers; + this.credentialReference = builder.credentialReference; + this.aliasFilter = builder.aliasFilter; + // File + this.path = builder.path; + this.relativeTo = builder.relativeTo; + this.required = builder.required; + // Replace existing + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address keyStoreAddress = Address.subsystem("elytron").and("key-store", name); + if (replaceExisting) { + ops.removeIfExists(keyStoreAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(keyStoreAddress, Values.empty() + .and("name", name) + .and("type", type) + .andObject("credential-reference", credentialReference.toValues()) + .andOptional("provider-name", providerName) + .andOptional("providers", providers) + .andOptional("alias-filter", aliasFilter) + .andOptional("path", path) + .andOptional("relative-to", relativeTo) + .andOptional("required", required)); + } + + @Override + public void apply(OfflineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + ctx.client.apply(GroovyXmlTransform.of(AddKeyStore.class) + .subtree("elytronSubsystem", Subtree.subsystem("elytron")) + .parameter("atrName", name) + .parameter("atrType", type) + .parameters(credentialReference.toParameters()) + .parameter("atrProviderName", providerName) + .parameter("atrProviders", providers) + .parameter("atrAliasFilter", aliasFilter) + .parameter("atrPath", path) + .parameter("atrRelativeTo", relativeTo) + .parameter("atrRequired", required) + .parameter("atrReplaceExisting", replaceExisting) + .build()); + } + + public static final class Builder { + + private final String name; + private String type; + private String providerName; + private String providers; + private CredentialRef credentialReference; + private String aliasFilter; + private String path; + private String relativeTo; + private Boolean required; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null || name.isEmpty()) { + throw new IllegalArgumentException("Name of the key-store must be specified as non empty value"); + } + this.name = name; + } + + public Builder type(String type) { + this.type = type; + return this; + } + + public Builder providerName(String providerName) { + this.providerName = providerName; + return this; + } + + public Builder providers(String providers) { + this.providers = providers; + return this; + } + + public Builder credentialReference(CredentialRef credentialReference) { + this.credentialReference = credentialReference; + return this; + } + + public Builder aliasFilter(String aliasFilter) { + this.aliasFilter = aliasFilter; + return this; + } + + public Builder path(String path) { + this.path = path; + return this; + } + + public Builder relativeTo(String relativeTo) { + this.relativeTo = relativeTo; + return this; + } + + public Builder required(Boolean required) { + this.required = required; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddKeyStore build() { + if (type == null || type.isEmpty()) { + throw new IllegalArgumentException("Type of the key-store must be specified as non empty value"); + } + if (credentialReference == null) { + throw new IllegalArgumentException("Credential reference of the key-store must be specified"); + } + return new AddKeyStore(this); + } + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AddLdapKeyStore.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AddLdapKeyStore.java new file mode 100644 index 00000000..b729143b --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AddLdapKeyStore.java @@ -0,0 +1,399 @@ +package org.wildfly.extras.creaper.commands.elytron.tls; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.jboss.dmr.ModelNode; +import org.wildfly.extras.creaper.commands.foundation.offline.xml.GroovyXmlTransform; +import org.wildfly.extras.creaper.commands.foundation.offline.xml.Subtree; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.offline.OfflineCommand; +import org.wildfly.extras.creaper.core.offline.OfflineCommandContext; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddLdapKeyStore implements OnlineCommand, OfflineCommand { + + private final String name; + private final String dirContext; + private final String searchPath; + private final Boolean searchRecursive; + private final Integer searchTimeLimit; + private final String filterAlias; + private final String filterCertificate; + private final String filterIterate; + private final String aliasAttribute; + private final String certificateAttribute; + private final String certificateType; + private final String certificateChainAttribute; + private final String certificateChainEncoding; + private final String keyAttribute; + private final String keyType; + private final NewItemTemplate newItemTemplate; + private final boolean replaceExisting; + + private AddLdapKeyStore(Builder builder) { + this.name = builder.name; + this.dirContext = builder.dirContext; + this.searchPath = builder.searchPath; + this.searchRecursive = builder.searchRecursive; + this.searchTimeLimit = builder.searchTimeLimit; + this.filterAlias = builder.filterAlias; + this.filterCertificate = builder.filterCertificate; + this.filterIterate = builder.filterIterate; + this.aliasAttribute = builder.aliasAttribute; + this.certificateAttribute = builder.certificateAttribute; + this.certificateType = builder.certificateType; + this.certificateChainAttribute = builder.certificateChainAttribute; + this.certificateChainEncoding = builder.certificateChainEncoding; + this.keyAttribute = builder.keyAttribute; + this.keyType = builder.keyType; + this.newItemTemplate = builder.newItemTemplate; + // Replace existing + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address keyStoreAddress = Address.subsystem("elytron").and("ldap-key-store", name); + if (replaceExisting) { + ops.removeIfExists(keyStoreAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + Values keyStoreValues = Values.empty() + .and("name", name) + .and("dir-context", dirContext) + .and("search-path", searchPath) + .andOptional("search-recursive", searchRecursive) + .andOptional("search-time-limit", searchTimeLimit) + .andOptional("filter-alias", filterAlias) + .andOptional("filter-certificate", filterCertificate) + .andOptional("filter-iterate", filterIterate) + .andOptional("alias-attribute", aliasAttribute) + .andOptional("certificate-attribute", certificateAttribute) + .andOptional("certificate-type", certificateType) + .andOptional("certificate-chain-attribute", certificateChainAttribute) + .andOptional("certificate-chain-encoding", certificateChainEncoding) + .andOptional("key-attribute", keyAttribute) + .andOptional("key-type", keyType); + + if (newItemTemplate != null) { + ModelNode newItemTemplateNode = new ModelNode(); + newItemTemplateNode.add("new-item-path", newItemTemplate.getNewItemPath()); + newItemTemplateNode.add("new-item-rdn", newItemTemplate.getNewItemRdn()); + if (newItemTemplate.getNewItemAttributes() != null && !newItemTemplate.getNewItemAttributes().isEmpty()) { + List newItemAttributesNodeList = new ArrayList(); + for (NewItemAttribute newItemAttribute : newItemTemplate.getNewItemAttributes()) { + ModelNode attributeNode = new ModelNode(); + + if (newItemAttribute.getName() != null && !newItemAttribute.getName().isEmpty()) { + attributeNode.add("name", newItemAttribute.getName()); + } + + ModelNode valuesList = new ModelNode().setEmptyList(); + for (String value : newItemAttribute.getValues()) { + valuesList.add(value); + } + attributeNode.add("value", valuesList); + + attributeNode = attributeNode.asObject(); + newItemAttributesNodeList.add(attributeNode); + } + ModelNode newItemAttributesNode = new ModelNode(); + newItemAttributesNode.set(newItemAttributesNodeList); + newItemTemplateNode.add("new-item-attributes", newItemAttributesNode); + } + newItemTemplateNode = newItemTemplateNode.asObject(); + keyStoreValues = keyStoreValues.and("new-item-template", newItemTemplateNode); + } + + ops.add(keyStoreAddress, keyStoreValues); + + } + + @Override + public void apply(OfflineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + ctx.client.apply(GroovyXmlTransform.of(AddLdapKeyStore.class) + .subtree("elytronSubsystem", Subtree.subsystem("elytron")) + .parameter("atrName", name) + .parameter("atrDirContext", dirContext) + .parameter("atrSearchPath", searchPath) + .parameter("atrSearchRecursive", searchRecursive) + .parameter("atrSearchTimeLimit", searchTimeLimit) + .parameter("atrFilterAlias", filterAlias) + .parameter("atrFilterCertificate", filterCertificate) + .parameter("atrFilterIterate", filterIterate) + .parameter("atrAliasAttribute", aliasAttribute) + .parameter("atrCertificateAttribute", certificateAttribute) + .parameter("atrCertificateType", certificateType) + .parameter("atrCertificateChainAttribute", certificateChainAttribute) + .parameter("atrCertificateChainEncoding", certificateChainEncoding) + .parameter("atrKeyAttribute", keyAttribute) + .parameter("atrKeyType", keyType) + .parameters(newItemTemplate != null ? newItemTemplate.toParameters() : NewItemTemplate.EMPTY_PARAMETERS) + .parameter("atrReplaceExisting", replaceExisting) + .build()); + } + + public static final class Builder { + + private final String name; + private String dirContext; + private String searchPath; + private Boolean searchRecursive; + private Integer searchTimeLimit; + private String filterAlias; + private String filterCertificate; + private String filterIterate; + private String aliasAttribute; + private String certificateAttribute; + private String certificateType; + private String certificateChainAttribute; + private String certificateChainEncoding; + private String keyAttribute; + private String keyType; + private NewItemTemplate newItemTemplate; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null || name.isEmpty()) { + throw new IllegalArgumentException("Name of the ldap-key-store must be specified as non empty value"); + } + this.name = name; + } + + public Builder dirContext(String dirContext) { + this.dirContext = dirContext; + return this; + } + + public Builder searchPath(String searchPath) { + this.searchPath = searchPath; + return this; + } + + public Builder searchRecursive(Boolean searchRecursive) { + this.searchRecursive = searchRecursive; + return this; + } + + public Builder searchTimeLimit(Integer searchTimeLimit) { + this.searchTimeLimit = searchTimeLimit; + return this; + } + + public Builder filterAlias(String filterAlias) { + this.filterAlias = filterAlias; + return this; + } + + public Builder filterCertificate(String filterCertificate) { + this.filterCertificate = filterCertificate; + return this; + } + + public Builder filterIterate(String filterIterate) { + this.filterIterate = filterIterate; + return this; + } + + public Builder aliasAttribute(String aliasAttribute) { + this.aliasAttribute = aliasAttribute; + return this; + } + + public Builder certificateAttribute(String certificateAttribute) { + this.certificateAttribute = certificateAttribute; + return this; + } + + public Builder certificateType(String certificateType) { + this.certificateType = certificateType; + return this; + } + + public Builder certificateChainAttribute(String certificateChainAttribute) { + this.certificateChainAttribute = certificateChainAttribute; + return this; + } + + public Builder certificateChainEncoding(String certificateChainEncoding) { + this.certificateChainEncoding = certificateChainEncoding; + return this; + } + + public Builder keyAttribute(String keyAttribute) { + this.keyAttribute = keyAttribute; + return this; + } + + public Builder keyType(String keyType) { + this.keyType = keyType; + return this; + } + + public Builder newItemTemplate(NewItemTemplate newItemTemplate) { + this.newItemTemplate = newItemTemplate; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + + public AddLdapKeyStore build() { + + if (dirContext == null || dirContext.isEmpty()) { + throw new IllegalArgumentException("Dir context of the ldap-key-store must be specified as non empty value"); + } + if (searchPath == null || searchPath.isEmpty()) { + throw new IllegalArgumentException("Search path of the ldap-key-store must be specified as non empty value"); + } + + return new AddLdapKeyStore(this); + } + } + + public static final class NewItemTemplate { + + static final Map EMPTY_PARAMETERS = new HashMap(); + + static { + EMPTY_PARAMETERS.put("atrNewItemAttributes", null); + EMPTY_PARAMETERS.put("atrNewItemPath", null); + EMPTY_PARAMETERS.put("atrNewItemRdn", null); + } + + private final List newItemAttributes; + private final String newItemPath; + private final String newItemRdn; + + + private NewItemTemplate(NewItemTemplateBuilder builder) { + this.newItemPath = builder.newItemPath; + this.newItemRdn = builder.newItemRdn; + this.newItemAttributes = builder.newItemAttributes; + } + + public String getNewItemPath() { + return newItemPath; + } + + public String getNewItemRdn() { + return newItemRdn; + } + + public List getNewItemAttributes() { + return newItemAttributes; + } + + public Map toParameters() { + Map parameters = new HashMap(); + parameters.put("atrNewItemAttributes", newItemAttributes); + parameters.put("atrNewItemPath", newItemPath); + parameters.put("atrNewItemRdn", newItemRdn); + return parameters; + } + } + + public static final class NewItemTemplateBuilder { + + private String newItemPath; + private String newItemRdn; + private List newItemAttributes = new ArrayList(); + + public NewItemTemplateBuilder newItemPath(String newItemPath) { + this.newItemPath = newItemPath; + return this; + } + + public NewItemTemplateBuilder newItemRdn(String newItemRdn) { + this.newItemRdn = newItemRdn; + return this; + } + + public NewItemTemplateBuilder addNewItemAttributes(NewItemAttribute... newItemAttributes) { + if (newItemAttributes == null) { + throw new IllegalArgumentException("NewItemAttributes added to ldap-key-store must not be null"); + } + Collections.addAll(this.newItemAttributes, newItemAttributes); + return this; + } + + public NewItemTemplate build() { + if (newItemPath == null || newItemPath.isEmpty()) { + throw new IllegalArgumentException("new-item-template.new-item-path of the ldap-key-store must be specified as non empty value"); + } + if (newItemRdn == null || newItemRdn.isEmpty()) { + throw new IllegalArgumentException("new-item-template.new-item-rdn of the ldap-key-store must be specified as non empty value"); + } + return new NewItemTemplate(this); + } + } + + public static final class NewItemAttribute { + + private final String name; + private final List values; + + private NewItemAttribute(NewItemAttributeBuilder builder) { + this.name = builder.name; + this.values = builder.values; + } + + public String getName() { + return name; + } + + public List getValues() { + return values; + } + + } + + public static final class NewItemAttributeBuilder { + + private String name; + private List values = new ArrayList(); + + public NewItemAttributeBuilder name(String name) { + this.name = name; + return this; + } + + public NewItemAttributeBuilder addValues(String... values) { + if (values == null) { + throw new IllegalArgumentException("Values added to NewIdentityAttributesBuilder for ldap-key-store must not be null"); + } + Collections.addAll(this.values, values); + return this; + } + + public NewItemAttribute build() { + if (values == null || values.isEmpty()) { + throw new IllegalArgumentException("values must not be null and must include at least one entry"); + } + return new NewItemAttribute(this); + } + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AddServerSSLContext.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AddServerSSLContext.java new file mode 100644 index 00000000..a304e613 --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AddServerSSLContext.java @@ -0,0 +1,199 @@ +package org.wildfly.extras.creaper.commands.elytron.tls; + +import org.wildfly.extras.creaper.commands.foundation.offline.xml.GroovyXmlTransform; +import org.wildfly.extras.creaper.commands.foundation.offline.xml.Subtree; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.offline.OfflineCommandContext; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddServerSSLContext extends AbstractAddSSLContext { + + private final Boolean authenticationOptional; + private final Boolean needClientAuth; + private final Boolean wantClientAuth; + private final Integer maximumSessionCacheSize; + private final Integer sessionTimeout; + private final String securityDomain; + private final String realmMapper; + private final String preRealmPrincipalTransformer; + private final String postRealmPrincipalTransformer; + private final String finalPrincipalTransformer; + private final Boolean useCipherSuitesOrder; + private final Boolean wrap; + + private AddServerSSLContext(Builder builder) { + super(builder); + this.authenticationOptional = builder.authenticationOptional; + this.needClientAuth = builder.needClientAuth; + this.wantClientAuth = builder.wantClientAuth; + this.maximumSessionCacheSize = builder.maximumSessionCacheSize; + this.sessionTimeout = builder.sessionTimeout; + this.securityDomain = builder.securityDomain; + this.realmMapper = builder.realmMapper; + this.preRealmPrincipalTransformer = builder.preRealmPrincipalTransformer; + this.postRealmPrincipalTransformer = builder.postRealmPrincipalTransformer; + this.finalPrincipalTransformer = builder.finalPrincipalTransformer; + this.useCipherSuitesOrder = builder.useCipherSuitesOrder; + this.wrap = builder.wrap; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address serverSSLContextAddress = Address.subsystem("elytron").and("server-ssl-context", name); + if (replaceExisting) { + ops.removeIfExists(serverSSLContextAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(serverSSLContextAddress, Values.empty() + .and("key-manager", keyManager) + .andOptional("cipher-suite-filter", cipherSuiteFilter) + .andOptional("maximum-session-cache-size", maximumSessionCacheSize) + .andOptional("session-timeout", sessionTimeout) + .andOptional("trust-manager", trustManager) + .andListOptional(String.class, "protocols", protocols) + .andOptional("authentication-optional", authenticationOptional) + .andOptional("need-client-auth", needClientAuth) + .andOptional("want-client-auth", wantClientAuth) + .andOptional("security-domain", securityDomain) + .andOptional("realm-mapper", realmMapper) + .andOptional("pre-realm-principal-transformer", preRealmPrincipalTransformer) + .andOptional("post-realm-principal-transformer", postRealmPrincipalTransformer) + .andOptional("final-principal-transformer", finalPrincipalTransformer) + .andOptional("use-cipher-suites-order", useCipherSuitesOrder) + .andOptional("wrap", wrap) + .andOptional("providers", providers) + .andOptional("provider-name", providerName)); + } + + @Override + public void apply(OfflineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + ctx.client.apply(GroovyXmlTransform.of(AddServerSSLContext.class) + .subtree("elytronSubsystem", Subtree.subsystem("elytron")) + .parameter("atrName", name) + .parameter("atrCipherSuiteFilter", cipherSuiteFilter) + .parameter("atrMaximumSessionCacheSize", maximumSessionCacheSize) + .parameter("atrSessionTimeout", sessionTimeout) + .parameter("atrKeyManager", keyManager) + .parameter("atrTrustManager", trustManager) + .parameter("atrProtocols", protocols != null ? joinList(protocols) : null) + .parameter("atrAuthenticationOptional", authenticationOptional) + .parameter("atrNeedClientAuth", needClientAuth) + .parameter("atrWantClientAuth", wantClientAuth) + .parameter("atrSecurityDomain", securityDomain) + .parameter("atrRealmMapper", realmMapper) + .parameter("atrPreRealmPrincipalTransformer", preRealmPrincipalTransformer) + .parameter("atrPostRealmPrincipalTransformer", postRealmPrincipalTransformer) + .parameter("atrFinalPrincipalTransformer", finalPrincipalTransformer) + .parameter("atrUseCipherSuitesOrder", useCipherSuitesOrder) + .parameter("atrWrap", wrap) + .parameter("atrProviders", providers) + .parameter("atrProviderName", providerName) + .parameter("atrReplaceExisting", replaceExisting) + .build()); + } + + public static final class Builder extends AbstractAddSSLContext.Builder { + + private Boolean authenticationOptional; + private Boolean needClientAuth; + private Boolean wantClientAuth; + private Integer maximumSessionCacheSize; + private Integer sessionTimeout; + private String securityDomain; + private String realmMapper; + private String preRealmPrincipalTransformer; + private String postRealmPrincipalTransformer; + private String finalPrincipalTransformer; + private Boolean useCipherSuitesOrder; + private Boolean wrap; + + public Builder(String name) { + super(name); + } + + public Builder authenticationOptional(Boolean authenticationOptional) { + this.authenticationOptional = authenticationOptional; + return this; + } + + public Builder needClientAuth(Boolean needClientAuth) { + this.needClientAuth = needClientAuth; + return this; + } + + public Builder wantClientAuth(Boolean wantClientAuth) { + this.wantClientAuth = wantClientAuth; + return this; + } + + public Builder maximumSessionCacheSize(Integer maximumSessionCacheSize) { + this.maximumSessionCacheSize = maximumSessionCacheSize; + return this; + } + + public Builder sessionTimeout(Integer sessionTimeout) { + this.sessionTimeout = sessionTimeout; + return this; + } + + public Builder securityDomain(String securityDomain) { + this.securityDomain = securityDomain; + return this; + } + + public Builder realmMapper(String realmMapper) { + this.realmMapper = realmMapper; + return this; + } + + public Builder preRealmPrincipalTransformer(String preRealmPrincipalTransformer) { + this.preRealmPrincipalTransformer = preRealmPrincipalTransformer; + return this; + } + + public Builder postRealmPrincipalTransformer(String postRealmPrincipalTransformer) { + this.postRealmPrincipalTransformer = postRealmPrincipalTransformer; + return this; + } + + public Builder finalPrincipalTransformer(String finalPrincipalTransformer) { + this.finalPrincipalTransformer = finalPrincipalTransformer; + return this; + } + + public Builder useCipherSuitesOrder(Boolean useCipherSuitesOrder) { + this.useCipherSuitesOrder = useCipherSuitesOrder; + return this; + } + + public Builder wrap(Boolean wrap) { + this.wrap = wrap; + return this; + } + + @Override + public AddServerSSLContext build() { + if (keyManager == null || keyManager.isEmpty()) { + throw new IllegalArgumentException("Key-manager must be specified as non empty value"); + } + return new AddServerSSLContext(this); + } + + + } + +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AddTrustManager.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AddTrustManager.java new file mode 100644 index 00000000..4fd652bd --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/elytron/tls/AddTrustManager.java @@ -0,0 +1,220 @@ +package org.wildfly.extras.creaper.commands.elytron.tls; + +import java.util.HashMap; +import java.util.Map; + +import org.wildfly.extras.creaper.commands.foundation.offline.xml.GroovyXmlTransform; +import org.wildfly.extras.creaper.commands.foundation.offline.xml.Subtree; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.offline.OfflineCommand; +import org.wildfly.extras.creaper.core.offline.OfflineCommandContext; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public final class AddTrustManager implements OnlineCommand, OfflineCommand { + + private final String name; + private final String algorithm; + private final String aliasFilter; + private final String keyStore; + private final String providerName; + private final String providers; + private final CertificateRevocationList certificateRevocationList; + private final boolean replaceExisting; + + private AddTrustManager(Builder builder) { + this.name = builder.name; + this.algorithm = builder.algorithm; + this.aliasFilter = builder.aliasFilter; + this.keyStore = builder.keyStore; + this.providerName = builder.providerName; + this.providers = builder.providers; + this.certificateRevocationList = builder.certificateRevocationList; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + Operations ops = new Operations(ctx.client); + Address trustManagerAddress = Address.subsystem("elytron").and("trust-manager", name); + if (replaceExisting) { + ops.removeIfExists(trustManagerAddress); + new Administration(ctx.client).reloadIfRequired(); + } + + ops.add(trustManagerAddress, Values.empty() + .and("name", name) + .and("key-store", keyStore) + .andOptional("algorithm", algorithm) + .andOptional("alias-filter", aliasFilter) + .andOptional("provider-name", providerName) + .andOptional("providers", providers) + .andObjectOptional("certificate-revocation-list", + certificateRevocationList != null ? certificateRevocationList.toValues() : null)); + } + + @Override + public void apply(OfflineCommandContext ctx) throws Exception { + if (ctx.version.lessThan(ServerVersion.VERSION_5_0_0)) { + throw new AssertionError("Elytron is available since WildFly 11."); + } + + ctx.client.apply(GroovyXmlTransform.of(AddTrustManager.class) + .subtree("elytronSubsystem", Subtree.subsystem("elytron")) + .parameter("atrName", name) + .parameter("atrAlgorithm", algorithm) + .parameter("atrAliasFilter", aliasFilter) + .parameter("atrKeyStore", keyStore) + .parameter("atrProviderName", providerName) + .parameter("atrProviders", providers) + .parameters(certificateRevocationList != null + ? certificateRevocationList.toParameters() : CertificateRevocationList.EMPTY_PARAMETERS) + .parameter("atrReplaceExisting", replaceExisting) + .build()); + } + + public static final class Builder { + + private final String name; + private String algorithm; + private String aliasFilter; + private String keyStore; + private String providerName; + private String providers; + private CertificateRevocationList certificateRevocationList; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null || name.isEmpty()) { + throw new IllegalArgumentException("Name of the trust-manager must be specified as non empty value"); + } + this.name = name; + } + + public Builder algorithm(String algorithm) { + this.algorithm = algorithm; + return this; + } + + public Builder aliasFilter(String aliasFilter) { + this.aliasFilter = aliasFilter; + return this; + } + + public Builder keyStore(String keyStore) { + this.keyStore = keyStore; + return this; + } + + public Builder providerName(String providerName) { + this.providerName = providerName; + return this; + } + + public Builder providers(String providers) { + this.providers = providers; + return this; + } + + public Builder certificateRevocationList(CertificateRevocationList certificateRevocationList) { + this.certificateRevocationList = certificateRevocationList; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddTrustManager build() { + return new AddTrustManager(this); + } + } + + public static final class CertificateRevocationList { + + static final Map EMPTY_PARAMETERS = new HashMap(); + + static { + EMPTY_PARAMETERS.put("atrCrl", false); + EMPTY_PARAMETERS.put("atrCrlPath", null); + EMPTY_PARAMETERS.put("atrCrlRelativeTo", null); + EMPTY_PARAMETERS.put("atrCrlMaximumCertPath", null); + } + + private final String path; + private final String relativeTo; + private final Integer maximumCertPath; + + private CertificateRevocationList(CertificateRevocationListBuilder builder) { + this.path = builder.path; + this.relativeTo = builder.relativeTo; + this.maximumCertPath = builder.maximumCertPath; + } + + public String getPath() { + return path; + } + + public String getRelativeTo() { + return relativeTo; + } + + public Integer getMaximumCertPath() { + return maximumCertPath; + } + + public Values toValues() { + return Values.empty() + .andOptional("path", path) + .andOptional("relative-to", relativeTo) + .andOptional("maximum-cert-path", maximumCertPath); + } + + public Map toParameters() { + Map parameters = new HashMap(); + parameters.put("atrCrl", true); + parameters.put("atrCrlPath", path); + parameters.put("atrCrlRelativeTo", relativeTo); + parameters.put("atrCrlMaximumCertPath", maximumCertPath); + return parameters; + } + } + + public static final class CertificateRevocationListBuilder { + private String path; + private String relativeTo; + private Integer maximumCertPath; + + public CertificateRevocationListBuilder path(String path) { + this.path = path; + return this; + } + + public CertificateRevocationListBuilder relativeTo(String relativeTo) { + this.relativeTo = relativeTo; + return this; + } + + public CertificateRevocationListBuilder maximumCertPath(int maximumCertPath) { + this.maximumCertPath = maximumCertPath; + return this; + } + + public CertificateRevocationList build() { + if (relativeTo != null && path == null) { + throw new IllegalArgumentException("relativeTo requires path to be set"); + } + return new CertificateRevocationList(this); + } + + } +} diff --git a/commands/src/main/java/org/wildfly/extras/creaper/commands/undertow/AddApplicationSecurityDomain.java b/commands/src/main/java/org/wildfly/extras/creaper/commands/undertow/AddApplicationSecurityDomain.java new file mode 100644 index 00000000..070edf1d --- /dev/null +++ b/commands/src/main/java/org/wildfly/extras/creaper/commands/undertow/AddApplicationSecurityDomain.java @@ -0,0 +1,110 @@ +package org.wildfly.extras.creaper.commands.undertow; + +import org.wildfly.extras.creaper.commands.foundation.offline.xml.GroovyXmlTransform; +import org.wildfly.extras.creaper.commands.foundation.offline.xml.Subtree; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.offline.OfflineCommand; +import org.wildfly.extras.creaper.core.offline.OfflineCommandContext; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +/** + * Command which adds application security domain to Undertow subsystem. + */ +public final class AddApplicationSecurityDomain implements OnlineCommand, OfflineCommand { + + private final String name; + private final String httpAuthenticationFactory; + private final Boolean overrideDeploymentConfig; + private final boolean replaceExisting; + + private AddApplicationSecurityDomain(Builder builder) { + this.name = builder.name; + this.httpAuthenticationFactory = builder.httpAuthenticationFactory; + this.overrideDeploymentConfig = builder.overrideDeploymentConfig; + this.replaceExisting = builder.replaceExisting; + } + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + // Undertow is available since WildFly 8, but some options are only available since WildFly 11; + // for now, restricting to WildFly 11 and above + ctx.version.assertAtLeast(ServerVersion.VERSION_5_0_0); + + Operations ops = new Operations(ctx.client); + Address address = Address.subsystem("undertow").and("application-security-domain", name); + if (replaceExisting) { + ops.removeIfExists(address); + new Administration(ctx.client).reloadIfRequired(); + } + Values params = Values.empty() + .and("http-authentication-factory", httpAuthenticationFactory) + .andOptional("override-deployment-config", overrideDeploymentConfig); + + ops.add(address, params); + } + + @Override + public void apply(OfflineCommandContext ctx) throws Exception { + // Undertow is available since WildFly 8, but some options are only available since WildFly 11; + // for now, restricting to WildFly 11 and above + ctx.version.assertAtLeast(ServerVersion.VERSION_5_0_0); + + ctx.client.apply(GroovyXmlTransform.of(AddApplicationSecurityDomain.class) + .subtree("undertowSubsystem", Subtree.subsystem("undertow")) + .parameter("atrName", name) + .parameter("atrHttpAuthenticationFactory", httpAuthenticationFactory) + .parameter("atrOverrideDeploymentConfig", overrideDeploymentConfig) + .parameter("atrReplaceExisting", replaceExisting) + .build()); + } + + public static final class Builder { + + private final String name; + private String httpAuthenticationFactory; + private Boolean overrideDeploymentConfig; + private boolean replaceExisting; + + public Builder(String name) { + if (name == null || name.isEmpty()) { + throw new IllegalArgumentException("Name of the application-security-domain must be specified as non empty value"); + } + this.name = name; + } + + /** + * Reference to the HttpAuthenticationFactory that should be used. + */ + public Builder httpAuthenticationFactory(String httpAuthenticationFactory) { + this.httpAuthenticationFactory = httpAuthenticationFactory; + return this; + } + + /** + * The references HttpServerAuthenticationMechanismFactory contains it's own policy configuration + * to control the authentication mechanisms it supports, if this attribute is set to 'true' + * that policy will override the methods specified within the deployment. + */ + public Builder overrideDeploymentConfig(boolean overrideDeploymentConfig) { + this.overrideDeploymentConfig = overrideDeploymentConfig; + return this; + } + + public Builder replaceExisting() { + this.replaceExisting = true; + return this; + } + + public AddApplicationSecurityDomain build() { + if (httpAuthenticationFactory == null || httpAuthenticationFactory.isEmpty()) { + throw new IllegalArgumentException("httpAuthenticationFactory is manadatory"); + } + return new AddApplicationSecurityDomain(this); + } + } +} diff --git a/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/credfactory/AddCustomCredentialSecurityFactory.groovy b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/credfactory/AddCustomCredentialSecurityFactory.groovy new file mode 100644 index 00000000..b045556a --- /dev/null +++ b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/credfactory/AddCustomCredentialSecurityFactory.groovy @@ -0,0 +1,32 @@ +customAttrs = ['name': atrName] +if (atrClassName != null) customAttrs['class-name'] = atrClassName +if (atrModule != null) customAttrs['module'] = atrModule + +def customDefinition = { + 'custom-credential-security-factory'(customAttrs) { + if (!atrConfiguration.isEmpty()) { + 'configuration' { + for ( item in atrConfiguration ) { + 'property'(['name': item.key, 'value': item.value]) + } + } + } + } +} + +def isExistingSecurityRealms = elytronSubsystem.'credential-security-factories'.any { it.name() == 'credential-security-factories' } +if (! isExistingSecurityRealms) { + elytronSubsystem.appendNode { 'credential-security-factories' customDefinition } + return +} + +def existingCustomElement = elytronSubsystem.'credential-security-factories'.'custom-credential-security-factory'.find { it.'@name' == atrName } +if (existingCustomElement && !atrReplaceExisting) { + throw new IllegalStateException("CustomCredentialSecurityFactory with name $atrName already exists in configuration. Use different name.") +} else { + if (existingCustomElement) { + existingCustomElement.replaceNode customDefinition + } else { + elytronSubsystem.'credential-security-factories'.appendNode customDefinition + } +} diff --git a/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPermissionMapper.groovy b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPermissionMapper.groovy new file mode 100644 index 00000000..12064ac1 --- /dev/null +++ b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPermissionMapper.groovy @@ -0,0 +1,32 @@ +customAttrs = ['name': atrName] +if (atrClassName != null) customAttrs['class-name'] = atrClassName +if (atrModule != null) customAttrs['module'] = atrModule + +def customDefinition = { + 'custom-permission-mapper'(customAttrs) { + if (!atrConfiguration.isEmpty()) { + 'configuration' { + for ( item in atrConfiguration ) { + 'property'(['name': item.key, 'value': item.value]) + } + } + } + } +} + +def isExistingMappers = elytronSubsystem.'mappers'.any { it.name() == 'mappers' } +if (! isExistingMappers) { + elytronSubsystem.appendNode { 'mappers' customDefinition } + return +} + +def existingCustomElement = elytronSubsystem.'mappers'.'custom-permission-mapper'.find { it.'@name' == atrName } +if (existingCustomElement && !atrReplaceExisting) { + throw new IllegalStateException("CustomPermissionMapper with name $atrName already exists in configuration. Use different name.") +} else { + if (existingCustomElement) { + existingCustomElement.replaceNode customDefinition + } else { + elytronSubsystem.'mappers'.appendNode customDefinition + } +} diff --git a/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalDecoder.groovy b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalDecoder.groovy new file mode 100644 index 00000000..8ba8d958 --- /dev/null +++ b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalDecoder.groovy @@ -0,0 +1,32 @@ +customAttrs = ['name': atrName] +if (atrClassName != null) customAttrs['class-name'] = atrClassName +if (atrModule != null) customAttrs['module'] = atrModule + +def customDefinition = { + 'custom-principal-decoder'(customAttrs) { + if (!atrConfiguration.isEmpty()) { + 'configuration' { + for ( item in atrConfiguration ) { + 'property'(['name': item.key, 'value': item.value]) + } + } + } + } +} + +def isExistingMappers = elytronSubsystem.'mappers'.any { it.name() == 'mappers' } +if (! isExistingMappers) { + elytronSubsystem.appendNode { 'mappers' customDefinition } + return +} + +def existingCustomElement = elytronSubsystem.'mappers'.'custom-principal-decoder'.find { it.'@name' == atrName } +if (existingCustomElement && !atrReplaceExisting) { + throw new IllegalStateException("CustomPrincipalDecoder with name $atrName already exists in configuration. Use different name.") +} else { + if (existingCustomElement) { + existingCustomElement.replaceNode customDefinition + } else { + elytronSubsystem.'mappers'.appendNode customDefinition + } +} diff --git a/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalTransformer.groovy b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalTransformer.groovy new file mode 100644 index 00000000..dc578a0c --- /dev/null +++ b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalTransformer.groovy @@ -0,0 +1,32 @@ +customAttrs = ['name': atrName] +if (atrClassName != null) customAttrs['class-name'] = atrClassName +if (atrModule != null) customAttrs['module'] = atrModule + +def customDefinition = { + 'custom-principal-transformer'(customAttrs) { + if (!atrConfiguration.isEmpty()) { + 'configuration' { + for ( item in atrConfiguration ) { + 'property'(['name': item.key, 'value': item.value]) + } + } + } + } +} + +def isExistingMappers = elytronSubsystem.'mappers'.any { it.name() == 'mappers' } +if (! isExistingMappers) { + elytronSubsystem.appendNode { 'mappers' customDefinition } + return +} + +def existingCustomElement = elytronSubsystem.'mappers'.'custom-principal-transformer'.find { it.'@name' == atrName } +if (existingCustomElement && !atrReplaceExisting) { + throw new IllegalStateException("CustomPrincipalTransformer with name $atrName already exists in configuration. Use different name.") +} else { + if (existingCustomElement) { + existingCustomElement.replaceNode customDefinition + } else { + elytronSubsystem.'mappers'.appendNode customDefinition + } +} diff --git a/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRealmMapper.groovy b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRealmMapper.groovy new file mode 100644 index 00000000..1829cd0f --- /dev/null +++ b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRealmMapper.groovy @@ -0,0 +1,32 @@ +customAttrs = ['name': atrName] +if (atrClassName != null) customAttrs['class-name'] = atrClassName +if (atrModule != null) customAttrs['module'] = atrModule + +def customDefinition = { + 'custom-realm-mapper'(customAttrs) { + if (!atrConfiguration.isEmpty()) { + 'configuration' { + for ( item in atrConfiguration ) { + 'property'(['name': item.key, 'value': item.value]) + } + } + } + } +} + +def isExistingMappers = elytronSubsystem.'mappers'.any { it.name() == 'mappers' } +if (! isExistingMappers) { + elytronSubsystem.appendNode { 'mappers' customDefinition } + return +} + +def existingCustomRealmMapper = elytronSubsystem.'mappers'.'custom-realm-mapper'.find { it.'@name' == atrName } +if (existingCustomRealmMapper && !atrReplaceExisting) { + throw new IllegalStateException("CustomRealmMapper with name $atrName already exists in configuration. Use different name.") +} else { + if (existingCustomRealmMapper) { + existingCustomRealmMapper.replaceNode customDefinition + } else { + elytronSubsystem.'mappers'.appendNode customDefinition + } +} diff --git a/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleDecoder.groovy b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleDecoder.groovy new file mode 100644 index 00000000..f2d7d15b --- /dev/null +++ b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleDecoder.groovy @@ -0,0 +1,32 @@ +customAttrs = ['name': atrName] +if (atrClassName != null) customAttrs['class-name'] = atrClassName +if (atrModule != null) customAttrs['module'] = atrModule + +def customDefinition = { + 'custom-role-decoder'(customAttrs) { + if (!atrConfiguration.isEmpty()) { + 'configuration' { + for ( item in atrConfiguration ) { + 'property'(['name': item.key, 'value': item.value]) + } + } + } + } +} + +def isExistingMappers = elytronSubsystem.'mappers'.any { it.name() == 'mappers' } +if (! isExistingMappers) { + elytronSubsystem.appendNode { 'mappers' customDefinition } + return +} + +def existingCustomRoleDecoder = elytronSubsystem.'mappers'.'custom-role-decoder'.find { it.'@name' == atrName } +if (existingCustomRoleDecoder && !atrReplaceExisting) { + throw new IllegalStateException("CustomRoleDecoder with name $atrName already exists in configuration. Use different name.") +} else { + if (existingCustomRoleDecoder) { + existingCustomRoleDecoder.replaceNode customDefinition + } else { + elytronSubsystem.'mappers'.appendNode customDefinition + } +} diff --git a/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleMapper.groovy b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleMapper.groovy new file mode 100644 index 00000000..ac00bdf8 --- /dev/null +++ b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleMapper.groovy @@ -0,0 +1,32 @@ +customAttrs = ['name': atrName] +if (atrClassName != null) customAttrs['class-name'] = atrClassName +if (atrModule != null) customAttrs['module'] = atrModule + +def customDefinition = { + 'custom-role-mapper'(customAttrs) { + if (!atrConfiguration.isEmpty()) { + 'configuration' { + for ( item in atrConfiguration ) { + 'property'(['name': item.key, 'value': item.value]) + } + } + } + } +} + +def isExistingMappers = elytronSubsystem.'mappers'.any { it.name() == 'mappers' } +if (! isExistingMappers) { + elytronSubsystem.appendNode { 'mappers' customDefinition } + return +} + +def existingCustomRoleMapper = elytronSubsystem.'mappers'.'custom-role-mapper'.find { it.'@name' == atrName } +if (existingCustomRoleMapper && !atrReplaceExisting) { + throw new IllegalStateException("CustomRoleMapper with name $atrName already exists in configuration. Use different name.") +} else { + if (existingCustomRoleMapper) { + existingCustomRoleMapper.replaceNode customDefinition + } else { + elytronSubsystem.'mappers'.appendNode customDefinition + } +} diff --git a/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/realm/AddCachingRealm.groovy b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/realm/AddCachingRealm.groovy new file mode 100644 index 00000000..1d2b8742 --- /dev/null +++ b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/realm/AddCachingRealm.groovy @@ -0,0 +1,25 @@ +cachingRealmAttrs = ['name': atrName] +if (atrRealm != null) cachingRealmAttrs['realm'] = atrRealm +if (atrMaximumEntries != null) cachingRealmAttrs['maximum-entries'] = atrMaximumEntries +if (atrMaximumAge != null) cachingRealmAttrs['maximum-age'] = atrMaximumAge + +def cachingRealmDefinition = { + 'caching-realm'(cachingRealmAttrs) +} + +def isExistingSecurityRealms = elytronSubsystem.'security-realms'.any { it.name() == 'security-realms' } +if (! isExistingSecurityRealms) { + elytronSubsystem.appendNode { 'security-realms' cachingRealmDefinition } + return +} + +def existingCachingRealm = elytronSubsystem.'security-realms'.'caching-realm'.find { it.'@name' == atrName } +if (existingCachingRealm && !atrReplaceExisting) { + throw new IllegalStateException("caching-realm with name $atrName already exists in configuration. Use different name.") +} else { + if (existingCachingRealm) { + existingCachingRealm.replaceNode cachingRealmDefinition + } else { + elytronSubsystem.'security-realms'.appendNode cachingRealmDefinition + } +} diff --git a/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomModifiableRealm.groovy b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomModifiableRealm.groovy new file mode 100644 index 00000000..96d379d8 --- /dev/null +++ b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomModifiableRealm.groovy @@ -0,0 +1,32 @@ +customAttrs = ['name': atrName] +if (atrClassName != null) customAttrs['class-name'] = atrClassName +if (atrModule != null) customAttrs['module'] = atrModule + +def customDefinition = { + 'custom-modifiable-realm'(customAttrs) { + if (!atrConfiguration.isEmpty()) { + 'configuration' { + for ( item in atrConfiguration ) { + 'property'(['name': item.key, 'value': item.value]) + } + } + } + } +} + +def isExistingSecurityRealms = elytronSubsystem.'security-realms'.any { it.name() == 'security-realms' } +if (! isExistingSecurityRealms) { + elytronSubsystem.appendNode { 'security-realms' customDefinition } + return +} + +def existingCustomElement = elytronSubsystem.'security-realms'.'custom-modifiable-realm'.find { it.'@name' == atrName } +if (existingCustomElement && !atrReplaceExisting) { + throw new IllegalStateException("CustomModifiableRealm with name $atrName already exists in configuration. Use different name.") +} else { + if (existingCustomElement) { + existingCustomElement.replaceNode customDefinition + } else { + elytronSubsystem.'security-realms'.appendNode customDefinition + } +} diff --git a/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomRealm.groovy b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomRealm.groovy new file mode 100644 index 00000000..8704f2ae --- /dev/null +++ b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomRealm.groovy @@ -0,0 +1,32 @@ +customAttrs = ['name': atrName] +if (atrClassName != null) customAttrs['class-name'] = atrClassName +if (atrModule != null) customAttrs['module'] = atrModule + +def customDefinition = { + 'custom-realm'(customAttrs) { + if (!atrConfiguration.isEmpty()) { + 'configuration' { + for ( item in atrConfiguration ) { + 'property'(['name': item.key, 'value': item.value]) + } + } + } + } +} + +def isExistingSecurityRealms = elytronSubsystem.'security-realms'.any { it.name() == 'security-realms' } +if (! isExistingSecurityRealms) { + elytronSubsystem.appendNode { 'security-realms' customDefinition } + return +} + +def existingCustomElement = elytronSubsystem.'security-realms'.'custom-realm'.find { it.'@name' == atrName } +if (existingCustomElement && !atrReplaceExisting) { + throw new IllegalStateException("CustomRealm with name $atrName already exists in configuration. Use different name.") +} else { + if (existingCustomElement) { + existingCustomElement.replaceNode customDefinition + } else { + elytronSubsystem.'security-realms'.appendNode customDefinition + } +} diff --git a/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/tls/AddClientSSLContext.groovy b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/tls/AddClientSSLContext.groovy new file mode 100644 index 00000000..6438f4fe --- /dev/null +++ b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/tls/AddClientSSLContext.groovy @@ -0,0 +1,34 @@ +sslContextAttrs = ['name': atrName] +if (atrCipherSuiteFilter != null) sslContextAttrs['cipher-suite-filter'] = atrCipherSuiteFilter +if (atrKeyManager != null) sslContextAttrs['key-manager'] = atrKeyManager +if (atrTrustManager != null) sslContextAttrs['trust-manager'] = atrTrustManager +if (atrProtocols != null) sslContextAttrs['protocols'] = atrProtocols +if (atrProviders != null) sslContextAttrs['providers'] = atrProviders +if (atrProviderName != null) sslContextAttrs['provider-name'] = atrProviderName + +def sslContextDefinition = { + 'client-ssl-context'(sslContextAttrs) +} + +def isExistingTls = elytronSubsystem.'tls'.any { it.name() == 'tls' } +if (! isExistingTls) { + elytronSubsystem.appendNode { 'tls' { 'client-ssl-contexts' sslContextDefinition } } + return +} + +def isExistingClientSslContexts = elytronSubsystem.'tls'.'client-ssl-contexts'.any { it.name() == 'client-ssl-contexts' } +if (! isExistingClientSslContexts) { + elytronSubsystem.'tls'.appendNode { 'client-ssl-contexts' sslContextDefinition } + return +} + +def existingClientSslContext = elytronSubsystem.'tls'.'client-ssl-contexts'.'client-ssl-context'.find { it.'@name' == atrName } +if (existingClientSslContext && !atrReplaceExisting) { + throw new IllegalStateException("Client SSL context with name $atrName already exists in configuration. Use different name.") +} else { + if (existingClientSslContext) { + existingClientSslContext.replaceNode sslContextDefinition + } else { + elytronSubsystem.'tls'.'client-ssl-contexts'.appendNode sslContextDefinition + } +} diff --git a/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/tls/AddFilteringKeyStore.groovy b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/tls/AddFilteringKeyStore.groovy new file mode 100644 index 00000000..e7ac8d8f --- /dev/null +++ b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/tls/AddFilteringKeyStore.groovy @@ -0,0 +1,30 @@ +keyStoreAttrs = ['name': atrName] +if (atrAliasFilter != null) keyStoreAttrs['alias-filter'] = atrAliasFilter +if (atrKeyStore != null) keyStoreAttrs['key-store'] = atrKeyStore + +def keyStoreDefinition = { + 'filtering-key-store'(keyStoreAttrs) +} + +def isExistingTls = elytronSubsystem.'tls'.any { it.name() == 'tls' } +if (! isExistingTls) { + elytronSubsystem.appendNode { 'tls' { 'key-stores' keyStoreDefinition } } + return +} + +def isExistingKeyStores = elytronSubsystem.'tls'.'key-stores'.any { it.name() == 'key-stores' } +if (! isExistingKeyStores) { + elytronSubsystem.'tls'.appendNode { 'key-stores' keyStoreDefinition } + return +} + +def existingKeyStore = elytronSubsystem.'tls'.'key-stores'.'filtering-key-store'.find { it.'@name' == atrName } +if (existingKeyStore && !atrReplaceExisting) { + throw new IllegalStateException("KeyStore with name $atrName already exists in configuration. Use different name.") +} else { + if (existingKeyStore) { + existingKeyStore.replaceNode keyStoreDefinition + } else { + elytronSubsystem.'tls'.'key-stores'.appendNode keyStoreDefinition + } +} diff --git a/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyManager.groovy b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyManager.groovy new file mode 100644 index 00000000..431ed2e4 --- /dev/null +++ b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyManager.groovy @@ -0,0 +1,40 @@ +keyManagerAttrs = ['name': atrName, 'key-store': atrKeyStore] +if (atrAlgorithm != null) keyManagerAttrs['algorithm'] = atrAlgorithm +if (atrAliasFilter != null) keyManagerAttrs['alias-filter'] = atrAliasFilter +if (atrProviderName != null) keyManagerAttrs['provider-name'] = atrProviderName +if (atrProviders != null) keyManagerAttrs['providers'] = atrProviders + +credentialReferenceAttrs = [:] +if (atrCredentialRefAlias != null) credentialReferenceAttrs['alias'] = atrCredentialRefAlias +if (atrCredentialRefType != null) credentialReferenceAttrs['type'] = atrCredentialRefType +if (atrCredentialRefStore != null) credentialReferenceAttrs['store'] = atrCredentialRefStore +if (atrCredentialRefClearText != null) credentialReferenceAttrs['clear-text'] = atrCredentialRefClearText + +def keyManagerDefinition = { + 'key-manager'(keyManagerAttrs) { + 'credential-reference'(credentialReferenceAttrs) + } +} + +def isExistingTls = elytronSubsystem.'tls'.any { it.name() == 'tls' } +if (! isExistingTls) { + elytronSubsystem.appendNode { 'tls' { 'key-managers' keyManagerDefinition } } + return +} + +def isExistingKeyManagers = elytronSubsystem.'tls'.'key-managers'.any { it.name() == 'key-managers' } +if (! isExistingKeyManagers) { + elytronSubsystem.'tls'.appendNode { 'key-managers' keyManagerDefinition } + return +} + +def existingKeyManager = elytronSubsystem.'tls'.'key-managers'.'key-manager'.find { it.'@name' == atrName } +if (existingKeyManager && !atrReplaceExisting) { + throw new IllegalStateException("KeyManager with name $atrName already exists in configuration. Use different name.") +} else { + if (existingKeyManager) { + existingKeyManager.replaceNode keyManagerDefinition + } else { + elytronSubsystem.'tls'.'key-managers'.appendNode keyManagerDefinition + } +} diff --git a/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyStore.groovy b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyStore.groovy new file mode 100644 index 00000000..743727c9 --- /dev/null +++ b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyStore.groovy @@ -0,0 +1,51 @@ +keyStoreAttrs = ['name': atrName] +if (atrAliasFilter != null) keyStoreAttrs['alias-filter'] = atrAliasFilter + +implementationAttrs = [:] +if (atrType != null) implementationAttrs['type'] = atrType +if (atrProviderName != null) implementationAttrs['provider-name'] = atrProviderName +if (atrProviders != null) implementationAttrs['providers'] = atrProviders + +fileAttrs = [:] +if (atrPath != null) fileAttrs['path'] = atrPath +if (atrRelativeTo != null) fileAttrs['relative-to'] = atrRelativeTo +if (atrRequired != null) fileAttrs['required'] = atrRequired + +credentialReferenceAttrs = [:] +if (atrCredentialRefAlias != null) credentialReferenceAttrs['alias'] = atrCredentialRefAlias +if (atrCredentialRefType != null) credentialReferenceAttrs['type'] = atrCredentialRefType +if (atrCredentialRefStore != null) credentialReferenceAttrs['store'] = atrCredentialRefStore +if (atrCredentialRefClearText != null) credentialReferenceAttrs['clear-text'] = atrCredentialRefClearText + +def keyStoreDefinition = { + 'key-store'(keyStoreAttrs) { + 'credential-reference'(credentialReferenceAttrs) + 'implementation'(implementationAttrs) + if (!fileAttrs.isEmpty()) { + 'file'(fileAttrs) + } + } +} + +def isExistingTls = elytronSubsystem.'tls'.any { it.name() == 'tls' } +if (! isExistingTls) { + elytronSubsystem.appendNode { 'tls' { 'key-stores' keyStoreDefinition } } + return +} + +def isExistingKeyStores = elytronSubsystem.'tls'.'key-stores'.any { it.name() == 'key-stores' } +if (! isExistingKeyStores) { + elytronSubsystem.'tls'.appendNode { 'key-stores' keyStoreDefinition } + return +} + +def existingKeyStore = elytronSubsystem.'tls'.'key-stores'.'key-store'.find { it.'@name' == atrName } +if (existingKeyStore && !atrReplaceExisting) { + throw new IllegalStateException("KeyStore with name $atrName already exists in configuration. Use different name.") +} else { + if (existingKeyStore) { + existingKeyStore.replaceNode keyStoreDefinition + } else { + elytronSubsystem.'tls'.'key-stores'.appendNode keyStoreDefinition + } +} diff --git a/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/tls/AddLdapKeyStore.groovy b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/tls/AddLdapKeyStore.groovy new file mode 100644 index 00000000..c6a9f577 --- /dev/null +++ b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/tls/AddLdapKeyStore.groovy @@ -0,0 +1,76 @@ +keyStoreAttrs = ['name': atrName, 'dir-context': atrDirContext] + +newItemTemplateAttrs = [:] +if (atrNewItemPath != null) newItemTemplateAttrs['new-item-path'] = atrNewItemPath +if (atrNewItemRdn != null) newItemTemplateAttrs['new-item-rdn'] = atrNewItemRdn + +searchAttrs = [:] +if (atrSearchPath != null) searchAttrs['path'] = atrSearchPath +if (atrSearchRecursive != null) searchAttrs['recursive'] = atrSearchRecursive +if (atrSearchTimeLimit != null) searchAttrs['time-limit'] = atrSearchTimeLimit +if (atrFilterAlias != null) searchAttrs['filter-alias'] = atrFilterAlias +if (atrFilterCertificate != null) searchAttrs['filter-certificate'] = atrFilterCertificate +if (atrFilterIterate != null) searchAttrs['filter-iterate'] = atrFilterIterate + +attributeMappingAttrs = [:] +if (atrAliasAttribute != null) attributeMappingAttrs['alias-attribute'] = atrAliasAttribute +if (atrCertificateAttribute != null) attributeMappingAttrs['certificate-attribute'] = atrCertificateAttribute +if (atrCertificateType != null) attributeMappingAttrs['certificate-type'] = atrCertificateType +if (atrCertificateChainAttribute != null) attributeMappingAttrs['certificate-chain-attribute'] = atrCertificateChainAttribute +if (atrCertificateChainEncoding != null) attributeMappingAttrs['certificate-chain-encoding'] = atrCertificateChainEncoding +if (atrKeyAttribute != null) attributeMappingAttrs['key-attribute'] = atrKeyAttribute +if (atrKeyType != null) attributeMappingAttrs['key-type'] = atrKeyType + +def keyStoreDefinition = { + 'ldap-key-store'(keyStoreAttrs) { + 'search'(searchAttrs) + if (!attributeMappingAttrs.isEmpty()) { + 'attribute-mapping'(attributeMappingAttrs) + } + if (!newItemTemplateAttrs.isEmpty()) { + 'new-item-template'(newItemTemplateAttrs) { + if (atrNewItemAttributes != null && !atrNewItemAttributes.isEmpty()) { + for (newItemAttribute in atrNewItemAttributes) { + 'attribute'(['name': newItemAttribute.name, 'value': resolveNewItemAttribute(newItemAttribute.values)]) + } + } + } + } + } +} + +def isExistingTls = elytronSubsystem.'tls'.any { it.name() == 'tls' } +if (! isExistingTls) { + elytronSubsystem.appendNode { 'tls' { 'key-stores' keyStoreDefinition } } + return +} + +def isExistingKeyStores = elytronSubsystem.'tls'.'key-stores'.any { it.name() == 'key-stores' } +if (! isExistingKeyStores) { + elytronSubsystem.'tls'.appendNode { 'key-stores' keyStoreDefinition } + return +} + +def existingKeyStore = elytronSubsystem.'tls'.'key-stores'.'ldap-key-store'.find { it.'@name' == atrName } +if (existingKeyStore && !atrReplaceExisting) { + throw new IllegalStateException("LdapKeyStore with name $atrName already exists in configuration. Use different name.") +} else { + if (existingKeyStore) { + existingKeyStore.replaceNode keyStoreDefinition + } else { + elytronSubsystem.'tls'.'key-stores'.appendNode keyStoreDefinition + } +} + +def resolveNewItemAttribute(List list) { + if (list == null || list.isEmpty()) { + return null + } + StringBuilder sb = new StringBuilder("") + for (String host : list) { + sb.append(host) + sb.append(" ") + } + sb.deleteCharAt(sb.length() - 1) + return sb.toString() +} diff --git a/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/tls/AddServerSSLContext.groovy b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/tls/AddServerSSLContext.groovy new file mode 100644 index 00000000..9fe56d9a --- /dev/null +++ b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/tls/AddServerSSLContext.groovy @@ -0,0 +1,46 @@ +sslContextAttrs = ['name': atrName] +if (atrCipherSuiteFilter != null) sslContextAttrs['cipher-suite-filter'] = atrCipherSuiteFilter +if (atrMaximumSessionCacheSize != null) sslContextAttrs['maximum-session-cache-size'] = atrMaximumSessionCacheSize +if (atrSessionTimeout != null) sslContextAttrs['session-timeout'] = atrSessionTimeout +if (atrKeyManager != null) sslContextAttrs['key-manager'] = atrKeyManager +if (atrTrustManager != null) sslContextAttrs['trust-manager'] = atrTrustManager +if (atrProtocols != null) sslContextAttrs['protocols'] = atrProtocols +if (atrAuthenticationOptional != null) sslContextAttrs['authentication-optional'] = atrAuthenticationOptional +if (atrNeedClientAuth != null) sslContextAttrs['need-client-auth'] = atrNeedClientAuth +if (atrWantClientAuth != null) sslContextAttrs['want-client-auth'] = atrWantClientAuth +if (atrSecurityDomain != null) sslContextAttrs['security-domain'] = atrSecurityDomain +if (atrRealmMapper != null) sslContextAttrs['realm-mapper'] = atrRealmMapper +if (atrPreRealmPrincipalTransformer != null) sslContextAttrs['pre-realm-principal-transformer'] = atrPreRealmPrincipalTransformer +if (atrPostRealmPrincipalTransformer != null) sslContextAttrs['post-realm-principal-transformer'] = atrPostRealmPrincipalTransformer +if (atrFinalPrincipalTransformer != null) sslContextAttrs['final-principal-transformer'] = atrFinalPrincipalTransformer +if (atrUseCipherSuitesOrder != null) sslContextAttrs['use-cipher-suites-order'] = atrUseCipherSuitesOrder +if (atrWrap != null) sslContextAttrs['wrap'] = atrWrap +if (atrProviders != null) sslContextAttrs['providers'] = atrProviders +if (atrProviderName != null) sslContextAttrs['provider-name'] = atrProviderName + +def sslContextDefinition = { + 'server-ssl-context'(sslContextAttrs) +} + +def isExistingTls = elytronSubsystem.'tls'.any { it.name() == 'tls' } +if (! isExistingTls) { + elytronSubsystem.appendNode { 'tls' { 'server-ssl-contexts' sslContextDefinition } } + return +} + +def isExistingServerSslContexts = elytronSubsystem.'tls'.'server-ssl-contexts'.any { it.name() == 'server-ssl-contexts' } +if (! isExistingServerSslContexts) { + elytronSubsystem.'tls'.appendNode { 'server-ssl-contexts' sslContextDefinition } + return +} + +def existingServerSslContext = elytronSubsystem.'tls'.'server-ssl-contexts'.'server-ssl-context'.find { it.'@name' == atrName } +if (existingServerSslContext && !atrReplaceExisting) { + throw new IllegalStateException("Server SSL context with name $atrName already exists in configuration. Use different name.") +} else { + if (existingServerSslContext) { + existingServerSslContext.replaceNode sslContextDefinition + } else { + elytronSubsystem.'tls'.'server-ssl-contexts'.appendNode sslContextDefinition + } +} diff --git a/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/tls/AddTrustManager.groovy b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/tls/AddTrustManager.groovy new file mode 100644 index 00000000..1365f104 --- /dev/null +++ b/commands/src/main/resources/org/wildfly/extras/creaper/commands/elytron/tls/AddTrustManager.groovy @@ -0,0 +1,44 @@ +trustManagerAttrs = ['name': atrName] +if (atrAlgorithm != null) trustManagerAttrs['algorithm'] = atrAlgorithm +if (atrAliasFilter != null) trustManagerAttrs['alias-filter'] = atrAliasFilter +if (atrKeyStore != null) trustManagerAttrs['key-store'] = atrKeyStore +if (atrProviderName != null) trustManagerAttrs['provider-name'] = atrProviderName +if (atrProviders != null) trustManagerAttrs['providers'] = atrProviders + +if (atrCrl) { + crlAttrs = [:] + if (atrCrlPath != null) crlAttrs['path'] = atrCrlPath + if (atrCrlRelativeTo != null) crlAttrs['relative-to'] = atrCrlRelativeTo + if (atrCrlMaximumCertPath != null) crlAttrs['maximum-cert-path'] = atrCrlMaximumCertPath +} + +def trustManagerDefinition = { + if (atrCrl) { + 'trust-manager'(trustManagerAttrs) { 'certificate-revocation-list'(crlAttrs) } + } else { + 'trust-manager'(trustManagerAttrs) + } +} + +def isExistingTls = elytronSubsystem.'tls'.any { it.name() == 'tls' } +if (! isExistingTls) { + elytronSubsystem.appendNode { 'tls' { 'trust-managers' trustManagerDefinition } } + return +} + +def isExistingTrustManagers = elytronSubsystem.'tls'.'trust-managers'.any { it.name() == 'trust-managers' } +if (! isExistingTrustManagers) { + elytronSubsystem.'tls'.appendNode { 'trust-managers' trustManagerDefinition } + return +} + +def existingTrustManager = elytronSubsystem.'tls'.'trust-managers'.'trust-manager'.find { it.'@name' == atrName } +if (existingTrustManager && !atrReplaceExisting) { + throw new IllegalStateException("TrustManager with name $atrName already exists in configuration. Use different name.") +} else { + if (existingTrustManager) { + existingTrustManager.replaceNode trustManagerDefinition + } else { + elytronSubsystem.'tls'.'trust-managers'.appendNode trustManagerDefinition + } +} diff --git a/commands/src/main/resources/org/wildfly/extras/creaper/commands/undertow/AddApplicationSecurityDomain.groovy b/commands/src/main/resources/org/wildfly/extras/creaper/commands/undertow/AddApplicationSecurityDomain.groovy new file mode 100644 index 00000000..e6f6e667 --- /dev/null +++ b/commands/src/main/resources/org/wildfly/extras/creaper/commands/undertow/AddApplicationSecurityDomain.groovy @@ -0,0 +1,21 @@ +appSecDomainAttrs = ['name': atrName, 'http-authentication-factory': atrHttpAuthenticationFactory] +if (atrOverrideDeploymentConfig != null) appSecDomainAttrs['override-deployment-config'] = atrOverrideDeploymentConfig + +def appSecDomainDefinition = { 'application-security-domain'(appSecDomainAttrs) } + +def isExistingAppSecDomains = undertowSubsystem.'application-security-domains'.any { it.name() == 'application-security-domains' } +if (! isExistingAppSecDomains) { + undertowSubsystem.appendNode { 'application-security-domains' appSecDomainDefinition } + return +} + +def existingAppSecDomain = undertowSubsystem.'application-security-domains'.'application-security-domain'.find { it.'@name' == atrName } +if (existingAppSecDomain && !atrReplaceExisting) { + throw new IllegalStateException("Application security domain with name $atrName already exists in configuration. Use different name.") +} else { + if (existingAppSecDomain) { + existingAppSecDomain.replaceNode appSecDomainDefinition + } else { + undertowSubsystem.'application-security-domains'.appendNode appSecDomainDefinition + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/AbstractAddCustomOfflineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/AbstractAddCustomOfflineTest.java new file mode 100644 index 00000000..0ee13673 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/AbstractAddCustomOfflineTest.java @@ -0,0 +1,276 @@ +package org.wildfly.extras.creaper.commands.elytron; + +import static org.junit.Assert.fail; +import static org.wildfly.extras.creaper.XmlAssert.assertXmlIdentical; + +import java.io.File; + +import org.custommonkey.xmlunit.XMLUnit; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.ManagementClient; +import org.wildfly.extras.creaper.core.offline.OfflineManagementClient; +import org.wildfly.extras.creaper.core.offline.OfflineOptions; + +import com.google.common.base.Charsets; +import com.google.common.io.Files; + +public abstract class AbstractAddCustomOfflineTest { + + protected static final String PARENT_TYPE = "PARENT_TYPE"; + protected static final String CUSTOM_TYPE = "CUSTOM_TYPE"; + protected static final String CUSTOM_NAME = "CUSTOM_NAME"; + protected static final String CLASS_NAME = "CLASS_NAME"; + protected static final String MODULE_NAME = "MODULE_NAME"; + + private static final String SUBSYSTEM_EMPTY = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_MAPPERS_EMPTY = "" + + "\n" + + " \n" + + " \n" + + " <" + PARENT_TYPE + ">\n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_SIMPLE = "" + + "\n" + + " \n" + + " \n" + + " <" + PARENT_TYPE + ">\n" + + " <" + CUSTOM_TYPE + " name=\"" + CUSTOM_NAME + "\" class-name=\"" + CLASS_NAME + "\" module=\"" + MODULE_NAME + "\">" + + " " + + " " + + " " + + " " + + " " + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_EXPECTED_REPLACE = "" + + "\n" + + " \n" + + " \n" + + " <" + PARENT_TYPE + ">\n" + + " <" + CUSTOM_TYPE + " name=\"" + CUSTOM_NAME + "\" class-name=\"" + CLASS_NAME + "\" module=\"" + MODULE_NAME + "\">" + + " " + + " " + + " " + + " " + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_SECOND_CUSTOM_REALM_MAPPER = "" + + "\n" + + " \n" + + " \n" + + " <" + PARENT_TYPE + ">\n" + + " <" + CUSTOM_TYPE + " name=\"" + CUSTOM_NAME + "\" class-name=\"" + CLASS_NAME + "\" module=\"" + MODULE_NAME + "\">" + + " " + + " " + + " " + + " " + + " " + + " <" + CUSTOM_TYPE + " name=\"" + CUSTOM_NAME + "_SUFFIX2\" class-name=\"" + CLASS_NAME + "\" module=\"" + MODULE_NAME + "\">" + + " " + + " " + + " " + + " " + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_FULL = "" + + "\n" + + " \n" + + " \n" + + " <" + PARENT_TYPE + ">\n" + + " <" + CUSTOM_TYPE + " name=\"" + CUSTOM_NAME + "\" class-name=\"" + CLASS_NAME + "\" module=\"" + MODULE_NAME + "\">" + + " " + + " " + + " " + + " " + + " " + + " \n" + + " \n" + + " \n" + + ""; + + @Rule + public final TemporaryFolder tmp = new TemporaryFolder(); + + @Before + public void setUp() { + XMLUnit.setNormalizeWhitespace(true); + } + + @Test + public void addSimpleToEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(convertSubsystem(SUBSYSTEM_EMPTY), cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AbstractAddCustom addCustom = getBuilder(getAddCustomName()) + .className(getClassName()) + .module(getModuleName()) + .addConfiguration("alias1", "value1") + .addConfiguration("alias2", "value2") + .build(); + + assertXmlIdentical(convertSubsystem(SUBSYSTEM_EMPTY), Files.toString(cfg, Charsets.UTF_8)); + client.apply(addCustom); + assertXmlIdentical(convertSubsystem(SUBSYSTEM_SIMPLE), Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addSimpleToMappersEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(convertSubsystem(SUBSYSTEM_MAPPERS_EMPTY), cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AbstractAddCustom addCustom = getBuilder(getAddCustomName()) + .className(getClassName()) + .module(getModuleName()) + .addConfiguration("alias1", "value1") + .addConfiguration("alias2", "value2") + .build(); + + assertXmlIdentical(convertSubsystem(SUBSYSTEM_MAPPERS_EMPTY), Files.toString(cfg, Charsets.UTF_8)); + client.apply(addCustom); + assertXmlIdentical(convertSubsystem(SUBSYSTEM_SIMPLE), Files.toString(cfg, Charsets.UTF_8)); + } + + @Test(expected = CommandFailedException.class) + public void existing() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(convertSubsystem(SUBSYSTEM_SIMPLE), cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AbstractAddCustom addCustom = getBuilder(getAddCustomName()) + .className(getClassName()) + .module(getModuleName()) + .addConfiguration("alias1", "value1") + .addConfiguration("alias2", "value2") + .build(); + + assertXmlIdentical(convertSubsystem(SUBSYSTEM_SIMPLE), Files.toString(cfg, Charsets.UTF_8)); + client.apply(addCustom); + + fail("Custom realm mapper customRoleMapper already exists in configuration, exception should be thrown"); + } + + @Test + public void overrideExisting() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(convertSubsystem(SUBSYSTEM_SIMPLE), cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AbstractAddCustom addCustom = getBuilder(getAddCustomName()) + .className(getClassName()) + .module(getModuleName()) + .addConfiguration("alias123", "value123") + .replaceExisting() + .build(); + + assertXmlIdentical(convertSubsystem(SUBSYSTEM_SIMPLE), Files.toString(cfg, Charsets.UTF_8)); + client.apply(addCustom); + assertXmlIdentical(convertSubsystem(SUBSYSTEM_EXPECTED_REPLACE), Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void overrideNonExisting() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(convertSubsystem(SUBSYSTEM_SIMPLE), cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AbstractAddCustom addCustom = getBuilder(getAddCustomName() + "_SUFFIX2") + .className(getClassName()) + .module(getModuleName()) + .addConfiguration("alias3", "value3") + .replaceExisting() + .build(); + + assertXmlIdentical(convertSubsystem(SUBSYSTEM_SIMPLE), Files.toString(cfg, Charsets.UTF_8)); + client.apply(addCustom); + assertXmlIdentical(convertSubsystem(SUBSYSTEM_SECOND_CUSTOM_REALM_MAPPER), Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addSecondCustomRoleMapper() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(convertSubsystem(SUBSYSTEM_SIMPLE), cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AbstractAddCustom addCustom = getBuilder(getAddCustomName() + "_SUFFIX2") + .className(getClassName()) + .module(getModuleName()) + .addConfiguration("alias3", "value3") + .build(); + + assertXmlIdentical(convertSubsystem(SUBSYSTEM_SIMPLE), Files.toString(cfg, Charsets.UTF_8)); + client.apply(addCustom); + assertXmlIdentical(convertSubsystem(SUBSYSTEM_SECOND_CUSTOM_REALM_MAPPER), Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addFullToEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(convertSubsystem(SUBSYSTEM_EMPTY), cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AbstractAddCustom addCustom = getBuilder(getAddCustomName()) + .className(getClassName()) + .module(getModuleName()) + .addConfiguration("alias1", "value1") + .addConfiguration("alias2", "value2") + .build(); + + assertXmlIdentical(convertSubsystem(SUBSYSTEM_EMPTY), Files.toString(cfg, Charsets.UTF_8)); + client.apply(addCustom); + assertXmlIdentical(convertSubsystem(SUBSYSTEM_FULL), Files.toString(cfg, Charsets.UTF_8)); + } + + public abstract String convertSubsystem(String subsystemString); + + public abstract String getAddCustomName(); + + public AbstractAddCustom.Builder getBuilder(String name) { + return (AbstractAddCustom.Builder) getBuilderObject(name); + } + + public abstract Object getBuilderObject(String name); + + public abstract String getModuleName(); + + public abstract String getClassName(); +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/AbstractElytronOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/AbstractElytronOnlineTest.java new file mode 100644 index 00000000..c4dfff59 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/AbstractElytronOnlineTest.java @@ -0,0 +1,140 @@ +package org.wildfly.extras.creaper.commands.elytron; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +import org.jboss.dmr.ModelNode; +import org.jboss.dmr.Property; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.exporter.ZipExporter; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.After; +import org.junit.Assume; +import org.junit.Before; +import org.junit.BeforeClass; +import org.wildfly.extras.creaper.core.ManagementClient; +import org.wildfly.extras.creaper.core.ServerVersion; +import org.wildfly.extras.creaper.core.online.Constants; +import org.wildfly.extras.creaper.core.online.ModelNodeResult; +import org.wildfly.extras.creaper.core.online.OnlineManagementClient; +import org.wildfly.extras.creaper.core.online.OnlineOptions; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.OperationException; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public abstract class AbstractElytronOnlineTest { + + protected OnlineManagementClient client; + protected Operations ops; + protected Administration administration; + + protected static final Address SUBSYSTEM_ADDRESS = Address.subsystem("elytron"); + + @BeforeClass + public static void checkServerVersionIsSupported() throws Exception { + // check version is supported + ServerVersion serverVersion + = ManagementClient.online(OnlineOptions.standalone().localDefault().build()).version(); + Assume.assumeTrue("Elytron is available since WildFly 11.", + serverVersion.greaterThanOrEqualTo(ServerVersion.VERSION_5_0_0)); + } + + @Before + public void setupCreaperForTest() throws IOException { + client = createManagementClient(); + ops = new Operations(client); + administration = new Administration(client); + } + + @After + public void tearDownCreaperForTest() throws IOException { + if (client != null) { + client.close(); + } + } + + protected static OnlineManagementClient createManagementClient() throws IOException { + return ManagementClient.online(OnlineOptions.standalone().localDefault().build()); + } + + protected void removeAllElytronChildrenType(final String childrenType) throws IOException, OperationException { + Operations ops = new Operations(client); + ModelNodeResult result = ops.readChildrenNames(SUBSYSTEM_ADDRESS, childrenType); + List realmNames = result.stringListValue(); + + for (String realmName : realmNames) { + final Address realmAddress = SUBSYSTEM_ADDRESS.and(childrenType, realmName); + + ops.removeIfExists(realmAddress); + } + } + + protected void checkAttribute(Address address, String attribute, String expectedValue) throws IOException { + ModelNodeResult readAttribute = ops.readAttribute(address, attribute); + readAttribute.assertSuccess("Read operation for " + attribute + " failed"); + assertEquals("Read operation for " + attribute + " return wrong value", expectedValue, + readAttribute.stringValue()); + } + + protected void checkAttribute(Address address, String attribute, List expectedValue) throws IOException { + ModelNodeResult readAttribute = ops.readAttribute(address, attribute); + readAttribute.assertSuccess("Read operation for " + attribute + " failed"); + assertEquals("Read operation for " + attribute + " return unexpected value", expectedValue, + readAttribute.stringListValue()); + } + + protected void checkAttributeObject(Address address, String attribute, String objectProperty, String expectedValue) + throws IOException { + ModelNodeResult readAttribute = ops.readAttribute(address, attribute); + readAttribute.assertSuccess("Read operation for " + attribute + " failed"); + assertEquals("Read operation for " + attribute + " return wrong value", expectedValue, + readAttribute.asObject().get(Constants.RESULT).get(objectProperty).asString()); + } + + protected void checkAttributeProperties(Address address, String attribute, List expectedValues) + throws IOException { + ModelNodeResult readAttribute = ops.readAttribute(address, attribute); + readAttribute.assertSuccess("Read operation for " + attribute + " failed"); + ModelNode result = readAttribute.get(Constants.RESULT); + List propertyList = result.asPropertyList(); + + if (propertyList.size() != expectedValues.size()) { + fail("Configuration properties size must be same as expected values size. Was [" + propertyList.size() + + "] and matches [" + expectedValues.size() + "]"); + } + + int numberOfMatches = 0; + for (Property property : propertyList) { + for (Property expected : expectedValues) { + if (property.getName().equals(expected.getName()) && property.getValue().equals(expected.getValue())) { + numberOfMatches++; + } + } + } + + if (propertyList.size() != numberOfMatches) { + fail("Configuration properties size must be same as number of matches. Was [" + propertyList.size() + + "] and matches [" + numberOfMatches + "]"); + } + } + + /** + * + * @param namePrefix - prefix of JAR name + * @param classes - classes which will be added to JAR + * @return - JAR file + * @throws IOException - exception + */ + protected static File createJar(String namePrefix, Class... classes) throws IOException { + File testJar = File.createTempFile(namePrefix, ".jar"); + JavaArchive jar = ShrinkWrap.create(JavaArchive.class) + .addClasses(classes); + jar.as(ZipExporter.class).exportTo(testJar, true); + return testJar; + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/CreateServerSSLContextOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/CreateServerSSLContextOnlineTest.java new file mode 100644 index 00000000..520e0a39 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/CreateServerSSLContextOnlineTest.java @@ -0,0 +1,211 @@ +package org.wildfly.extras.creaper.commands.elytron; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.Arrays; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.tls.AbstractAddSSLContextOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class CreateServerSSLContextOnlineTest extends AbstractAddSSLContextOnlineTest { + + private static final String SERVER_SSL_CONTEXT_PROTOCOL = "TLSv1.2"; + private static final String PASSWORD = "secret"; + private static final String SERVER_SSL_CONTEXT_NAME = "CreaperTestServerSSLContext"; + private static final Address SERVER_SSL_CONTEXT_ADDRESS = SUBSYSTEM_ADDRESS.and("server-ssl-context", + SERVER_SSL_CONTEXT_NAME); + private static final Address KEY_STORE_ADDRESS = SUBSYSTEM_ADDRESS.and("key-store", + "key-store-name_" + SERVER_SSL_CONTEXT_NAME); + private static final Address KEY_MANAGER_ADDRESS = SUBSYSTEM_ADDRESS.and("key-manager", + "key-manager-name_" + SERVER_SSL_CONTEXT_NAME); + private static final Address TRUST_STORE_ADDRESS = SUBSYSTEM_ADDRESS.and("key-store", + "trust-store-name_" + SERVER_SSL_CONTEXT_NAME); + private static final Address TRUST_MANAGER_ADDRESS = SUBSYSTEM_ADDRESS.and("trust-manager", + "trust-manager-name_" + SERVER_SSL_CONTEXT_NAME); + + + private static final String SERVER_SSL_CONTEXT_NAME2 = "CreaperTestServerSSLContext2"; + private static final Address SERVER_SSL_CONTEXT_ADDRESS2 = SUBSYSTEM_ADDRESS.and("server-ssl-context", + SERVER_SSL_CONTEXT_NAME2); + private static final Address KEY_STORE_ADDRESS2 = SUBSYSTEM_ADDRESS.and("key-store", + "key-store-name_" + SERVER_SSL_CONTEXT_NAME2); + private static final Address KEY_MANAGER_ADDRESS2 = SUBSYSTEM_ADDRESS.and("key-manager", + "key-manager-name_" + SERVER_SSL_CONTEXT_NAME2); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(SERVER_SSL_CONTEXT_ADDRESS); + ops.removeIfExists(KEY_MANAGER_ADDRESS); + ops.removeIfExists(KEY_STORE_ADDRESS); + ops.removeIfExists(TRUST_MANAGER_ADDRESS); + ops.removeIfExists(TRUST_STORE_ADDRESS); + ops.removeIfExists(SERVER_SSL_CONTEXT_ADDRESS2); + ops.removeIfExists(KEY_MANAGER_ADDRESS2); + ops.removeIfExists(KEY_STORE_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleServerSSLContext() throws Exception { + CreateServerSSLContext createServerSSLContext = new CreateServerSSLContext.Builder(SERVER_SSL_CONTEXT_NAME) + .keyStorePassword(PASSWORD) + .keyPassword(PASSWORD) + .build(); + assertFalse("The server ssl context should not exist", ops.exists(SERVER_SSL_CONTEXT_ADDRESS)); + client.apply(createServerSSLContext); + assertTrue("Server ssl context should be created", ops.exists(SERVER_SSL_CONTEXT_ADDRESS)); + } + + @Test + public void addTwoSimpleServerSSLContexts() throws Exception { + CreateServerSSLContext createServerSSLContext = new CreateServerSSLContext.Builder(SERVER_SSL_CONTEXT_NAME) + .keyStorePassword(PASSWORD) + .keyPassword(PASSWORD) + .build(); + CreateServerSSLContext createServerSSLContext2 = new CreateServerSSLContext.Builder(SERVER_SSL_CONTEXT_NAME2) + .keyStorePassword(PASSWORD) + .keyPassword(PASSWORD) + .build(); + + assertFalse("The server ssl context should not exist", ops.exists(SERVER_SSL_CONTEXT_ADDRESS)); + assertFalse("The server ssl context should not exist", ops.exists(SERVER_SSL_CONTEXT_ADDRESS2)); + + client.apply(createServerSSLContext); + client.apply(createServerSSLContext2); + + assertTrue("Server SSL context should be created", ops.exists(SERVER_SSL_CONTEXT_ADDRESS)); + assertTrue("Server SSL context should be created", ops.exists(SERVER_SSL_CONTEXT_ADDRESS2)); + } + + @Test(expected = CommandFailedException.class) + public void addDuplicateServerSSLContextNotAllowed() throws Exception { + CreateServerSSLContext createServerSSLContext = new CreateServerSSLContext.Builder(SERVER_SSL_CONTEXT_NAME) + .keyStorePassword(PASSWORD) + .keyPassword(PASSWORD) + .build(); + CreateServerSSLContext createServerSSLContext2 = new CreateServerSSLContext.Builder(SERVER_SSL_CONTEXT_NAME) + .keyStorePassword(PASSWORD) + .keyPassword(PASSWORD) + .build(); + client.apply(createServerSSLContext); + assertTrue("The server ssl context should be created", ops.exists(SERVER_SSL_CONTEXT_ADDRESS)); + client.apply(createServerSSLContext2); + fail("Server ssl context is already configured, exception should be thrown"); + } + + @Test + public void addFullServerSSLContext() throws Exception { + CreateServerSSLContext createServerSSLContext = new CreateServerSSLContext.Builder(SERVER_SSL_CONTEXT_NAME) + .keyStorePassword(PASSWORD) + .keyPassword(PASSWORD) + .cipherSuiteFilter("ALL") + .protocols(SERVER_SSL_CONTEXT_PROTOCOL) + .maximumSessionCacheSize(0) + .sessionTimeout(0) + .needClientAuth(true) + .wantClientAuth(true) + .authenticationOptional(true) + .securityDomain("ApplicationDomain") + .algorithm("PKIX") + .keyStoreAlias("alias") + .keyStorePath("/path") + .keyStoreRelativeTo("jboss.server.config.dir") + .keyStoreRequired(false) + .keyStoreType("JKS") + .trustStoreAlias("alias") + .trustStorePassword(PASSWORD) + .trustStorePath("/path") + .trustStoreRelativeTo("jboss.server.config.dir") + .trustStoreRequired(false) + .build(); + client.apply(createServerSSLContext); + assertTrue("The server ssl context should be created", ops.exists(SERVER_SSL_CONTEXT_ADDRESS)); + + checkAttribute(SERVER_SSL_CONTEXT_ADDRESS, "cipher-suite-filter", "ALL"); + checkAttribute(SERVER_SSL_CONTEXT_ADDRESS, "maximum-session-cache-size", "0"); + checkAttribute(SERVER_SSL_CONTEXT_ADDRESS, "session-timeout", "0"); + checkAttribute(SERVER_SSL_CONTEXT_ADDRESS, "protocols", Arrays.asList(SERVER_SSL_CONTEXT_PROTOCOL)); + checkAttribute(SERVER_SSL_CONTEXT_ADDRESS, "need-client-auth", "true"); + checkAttribute(SERVER_SSL_CONTEXT_ADDRESS, "want-client-auth", "true"); + checkAttribute(SERVER_SSL_CONTEXT_ADDRESS, "authentication-optional", "true"); + checkAttribute(SERVER_SSL_CONTEXT_ADDRESS, "security-domain", "ApplicationDomain"); + checkAttribute(KEY_STORE_ADDRESS, "credential-reference.clear-text", PASSWORD); + checkAttribute(KEY_STORE_ADDRESS, "alias-filter", "alias"); + checkAttribute(KEY_STORE_ADDRESS, "path", "/path"); + checkAttribute(KEY_STORE_ADDRESS, "relative-to", "jboss.server.config.dir"); + checkAttribute(KEY_STORE_ADDRESS, "required", "false"); + checkAttribute(KEY_STORE_ADDRESS, "type", "JKS"); + checkAttribute(TRUST_STORE_ADDRESS, "credential-reference.clear-text", PASSWORD); + checkAttribute(TRUST_STORE_ADDRESS, "alias-filter", "alias"); + checkAttribute(TRUST_STORE_ADDRESS, "path", "/path"); + checkAttribute(TRUST_STORE_ADDRESS, "relative-to", "jboss.server.config.dir"); + checkAttribute(TRUST_STORE_ADDRESS, "required", "false"); + checkAttribute(TRUST_STORE_ADDRESS, "type", "JKS"); + checkAttribute(KEY_MANAGER_ADDRESS, "credential-reference.clear-text", PASSWORD); + checkAttribute(KEY_MANAGER_ADDRESS, "algorithm", "PKIX"); + checkAttribute(TRUST_MANAGER_ADDRESS, "algorithm", "PKIX"); + } + + @Test(expected = IllegalArgumentException.class) + public void addServerSSLContext_nullName() throws Exception { + new CreateServerSSLContext.Builder(null) + .keyStorePassword(PASSWORD) + .keyPassword(PASSWORD) + .build(); + fail("Creating command with null server SSL context name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addServerSSLContext_emptyName() throws Exception { + new CreateServerSSLContext.Builder("") + .keyStorePassword(PASSWORD) + .keyPassword(PASSWORD) + .build(); + fail("Creating command with empty server ssl context name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addServerSSLContext_nullKeyStorePassword() throws Exception { + new CreateServerSSLContext.Builder(SERVER_SSL_CONTEXT_NAME) + .keyStorePassword(null) + .keyPassword(PASSWORD) + .build(); + fail("Creating command with null key store password should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addServerSSLContext_emptyKeyStorePassword() throws Exception { + new CreateServerSSLContext.Builder(SERVER_SSL_CONTEXT_NAME) + .keyStorePassword("") + .keyPassword(PASSWORD) + .build(); + fail("Creating command with empty key store password should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addServerSSLContext_nullKeyPassword() throws Exception { + new CreateServerSSLContext.Builder(SERVER_SSL_CONTEXT_NAME) + .keyStorePassword(PASSWORD) + .keyPassword(null) + .build(); + fail("Creating command with null key password should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addServerSSLContext_emptyKeyPassword() throws Exception { + new CreateServerSSLContext.Builder(SERVER_SSL_CONTEXT_NAME) + .keyStorePassword(PASSWORD) + .keyPassword("") + .build(); + fail("Creating command with empty key password should throw exception"); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/audit/AddAggregateSecurityEventListenerOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/audit/AddAggregateSecurityEventListenerOnlineTest.java new file mode 100644 index 00000000..40bc4f44 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/audit/AddAggregateSecurityEventListenerOnlineTest.java @@ -0,0 +1,209 @@ +package org.wildfly.extras.creaper.commands.elytron.audit; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.OnlineManagementClient; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +@RunWith(Arquillian.class) +public class AddAggregateSecurityEventListenerOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_AGGREGATE_SECURITY_EVENT_LISTENER_NAME = "CreaperTestAggregateSecurityEventListener"; + private static final Address TEST_AGGREGATE_SECURITY_EVENT_LISTENER_ADDRESS = SUBSYSTEM_ADDRESS.and("aggregate-security-event-listener", + TEST_AGGREGATE_SECURITY_EVENT_LISTENER_NAME); + private static final String TEST_AGGREGATE_SECURITY_EVENT_LISTENER_NAME2 = "CreaperTestAggregateSecurityEventListener2"; + private static final Address TEST_AGGREGATE_SECURITY_EVENT_LISTENER_ADDRESS2 = SUBSYSTEM_ADDRESS.and("aggregate-security-event-listener", + TEST_AGGREGATE_SECURITY_EVENT_LISTENER_NAME2); + + private static final String TEST_FILE_AUDIT_LOG_NAME = "CreaperTestFileAuditLog"; + private static final Address TEST_FILE_AUDIT_LOG_ADDRESS = SUBSYSTEM_ADDRESS + .and("file-audit-log", TEST_FILE_AUDIT_LOG_NAME); + private static final String TEST_FILE_AUDIT_LOG_NAME2 = "CreaperTestFileAuditLog2"; + private static final Address TEST_FILE_AUDIT_LOG_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("file-audit-log", TEST_FILE_AUDIT_LOG_NAME2); + private static final String TEST_SYSLOG_AUDIT_LOG_NAME = "CreaperTestSyslogAuditLog"; + private static final Address TEST_SYSLOG_AUDIT_LOG_ADDRESS = SUBSYSTEM_ADDRESS + .and("syslog-audit-log", TEST_SYSLOG_AUDIT_LOG_NAME); + + @BeforeClass + public static void createElytronAuditLogs() throws Exception { + OnlineManagementClient client = null; + try { + client = createManagementClient(); + AddFileAuditLog addFileAuditLog = new AddFileAuditLog.Builder(TEST_FILE_AUDIT_LOG_NAME) + .path("audit.log") + .build(); + client.apply(addFileAuditLog); + AddFileAuditLog addFileAuditLog2 = new AddFileAuditLog.Builder(TEST_FILE_AUDIT_LOG_NAME2) + .path("second-audit.log") + .build(); + client.apply(addFileAuditLog2); + + AddSyslogAuditLog addSyslogAuditLog = new AddSyslogAuditLog.Builder(TEST_SYSLOG_AUDIT_LOG_NAME) + .serverAddress("localhost") + .port(9898) + .hostName("Elytron-audit") + .build(); + client.apply(addSyslogAuditLog); + } finally { + if (client != null) { + client.close(); + } + } + } + + @AfterClass + public static void removeElytronAuditLogs() throws Exception { + OnlineManagementClient client = null; + try { + client = createManagementClient(); + Operations ops = new Operations(client); + ops.removeIfExists(TEST_FILE_AUDIT_LOG_ADDRESS); + ops.removeIfExists(TEST_FILE_AUDIT_LOG_ADDRESS2); + ops.removeIfExists(TEST_SYSLOG_AUDIT_LOG_ADDRESS); + } finally { + if (client != null) { + client.close(); + } + } + } + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_AGGREGATE_SECURITY_EVENT_LISTENER_ADDRESS); + ops.removeIfExists(TEST_AGGREGATE_SECURITY_EVENT_LISTENER_ADDRESS2); + + administration.reloadIfRequired(); + } + + @Test + public void addAggregateSecurityEventListener() throws Exception { + AddAggregateSecurityEventListener addAggregateSecurityEventListener + = new AddAggregateSecurityEventListener.Builder(TEST_AGGREGATE_SECURITY_EVENT_LISTENER_NAME) + .addSecurityEventListeners(TEST_FILE_AUDIT_LOG_NAME, TEST_SYSLOG_AUDIT_LOG_NAME) + .build(); + + client.apply(addAggregateSecurityEventListener); + + assertTrue("Aggregate security event listener should be created", + ops.exists(TEST_AGGREGATE_SECURITY_EVENT_LISTENER_ADDRESS)); + checkAttribute(TEST_AGGREGATE_SECURITY_EVENT_LISTENER_ADDRESS, "security-event-listeners[0]", + TEST_FILE_AUDIT_LOG_NAME); + checkAttribute(TEST_AGGREGATE_SECURITY_EVENT_LISTENER_ADDRESS, "security-event-listeners[1]", + TEST_SYSLOG_AUDIT_LOG_NAME); + } + + @Test + public void addTwoAggregateSecurityEventListeners() throws Exception { + AddAggregateSecurityEventListener addAggregateSecurityEventListener + = new AddAggregateSecurityEventListener.Builder(TEST_AGGREGATE_SECURITY_EVENT_LISTENER_NAME) + .addSecurityEventListeners(TEST_FILE_AUDIT_LOG_NAME, TEST_SYSLOG_AUDIT_LOG_NAME) + .build(); + AddAggregateSecurityEventListener addAggregateSecurityEventListener2 + = new AddAggregateSecurityEventListener.Builder(TEST_AGGREGATE_SECURITY_EVENT_LISTENER_NAME2) + .addSecurityEventListeners(TEST_FILE_AUDIT_LOG_NAME, TEST_SYSLOG_AUDIT_LOG_NAME) + .build(); + + client.apply(addAggregateSecurityEventListener); + client.apply(addAggregateSecurityEventListener2); + + assertTrue("Aggregate security event listener should be created", + ops.exists(TEST_AGGREGATE_SECURITY_EVENT_LISTENER_ADDRESS)); + assertTrue("Second aggregate security event listener should be created", + ops.exists(TEST_AGGREGATE_SECURITY_EVENT_LISTENER_ADDRESS2)); + } + + @Test(expected = CommandFailedException.class) + public void addExistAggregateSecurityEventListenersNotAllowed() throws Exception { + AddAggregateSecurityEventListener addAggregateSecurityEventListener + = new AddAggregateSecurityEventListener.Builder(TEST_AGGREGATE_SECURITY_EVENT_LISTENER_NAME) + .addSecurityEventListeners(TEST_FILE_AUDIT_LOG_NAME, TEST_SYSLOG_AUDIT_LOG_NAME) + .build(); + AddAggregateSecurityEventListener addAggregateSecurityEventListener2 + = new AddAggregateSecurityEventListener.Builder(TEST_AGGREGATE_SECURITY_EVENT_LISTENER_NAME) + .addSecurityEventListeners(TEST_FILE_AUDIT_LOG_NAME, TEST_SYSLOG_AUDIT_LOG_NAME) + .build(); + + client.apply(addAggregateSecurityEventListener); + assertTrue("Aggregate security event listener should be created", + ops.exists(TEST_AGGREGATE_SECURITY_EVENT_LISTENER_ADDRESS)); + client.apply(addAggregateSecurityEventListener2); + fail("Aggregate security event listener CreaperTestAggregateSecurityEventListener already exists in configuration, exception should be thrown"); + } + + @Test(expected = CommandFailedException.class) + public void addExistAggregateSecurityEventListenersAllowed() throws Exception { + AddAggregateSecurityEventListener addAggregateSecurityEventListener + = new AddAggregateSecurityEventListener.Builder(TEST_AGGREGATE_SECURITY_EVENT_LISTENER_NAME) + .addSecurityEventListeners(TEST_FILE_AUDIT_LOG_NAME, TEST_SYSLOG_AUDIT_LOG_NAME) + .build(); + AddAggregateSecurityEventListener addAggregateSecurityEventListener2 + = new AddAggregateSecurityEventListener.Builder(TEST_AGGREGATE_SECURITY_EVENT_LISTENER_NAME) + .addSecurityEventListeners(TEST_FILE_AUDIT_LOG_NAME, TEST_FILE_AUDIT_LOG_NAME2) + .build(); + + client.apply(addAggregateSecurityEventListener); + assertTrue("Aggregate security event listener should be created", + ops.exists(TEST_AGGREGATE_SECURITY_EVENT_LISTENER_ADDRESS)); + client.apply(addAggregateSecurityEventListener2); + + // check whether it was really rewritten + checkAttribute(TEST_AGGREGATE_SECURITY_EVENT_LISTENER_ADDRESS, "security-event-listeners[1]", + TEST_FILE_AUDIT_LOG_NAME2); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregateSecurityEventListener_nullName() throws Exception { + new AddAggregateSecurityEventListener.Builder(null) + .addSecurityEventListeners(TEST_FILE_AUDIT_LOG_NAME, TEST_SYSLOG_AUDIT_LOG_NAME) + .build(); + + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregateSecurityEventListener_emptyName() throws Exception { + new AddAggregateSecurityEventListener.Builder("") + .addSecurityEventListeners(TEST_FILE_AUDIT_LOG_NAME, TEST_SYSLOG_AUDIT_LOG_NAME) + .build(); + + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregateSecurityEventListener_nullSecurityEventListeners() throws Exception { + new AddAggregateSecurityEventListener.Builder(TEST_AGGREGATE_SECURITY_EVENT_LISTENER_NAME) + .addSecurityEventListeners(null) + .build(); + + fail("Creating command with null security-event-listener name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregateSecurityEventListener_emptySecurityEventListeners() throws Exception { + new AddAggregateSecurityEventListener.Builder(TEST_AGGREGATE_SECURITY_EVENT_LISTENER_NAME) + .addSecurityEventListeners("") + .build(); + + fail("Creating command with empty security-event-listener name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregateSecurityEventListener_oneSecurityEventListener() throws Exception { + new AddAggregateSecurityEventListener.Builder(TEST_AGGREGATE_SECURITY_EVENT_LISTENER_NAME) + .addSecurityEventListeners(TEST_FILE_AUDIT_LOG_NAME) + .build(); + + fail("Creating command with only one security-event-listener name should throw exception"); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/audit/AddFileAuditLogOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/audit/AddFileAuditLogOnlineTest.java new file mode 100644 index 00000000..eed909c7 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/audit/AddFileAuditLogOnlineTest.java @@ -0,0 +1,144 @@ +package org.wildfly.extras.creaper.commands.elytron.audit; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +@RunWith(Arquillian.class) +public class AddFileAuditLogOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_FILE_AUDIT_LOG_NAME = "CreaperTestFileAuditLog"; + private static final Address TEST_FILE_AUDIT_LOG_ADDRESS = SUBSYSTEM_ADDRESS + .and("file-audit-log", TEST_FILE_AUDIT_LOG_NAME); + private static final String TEST_FILE_AUDIT_LOG_NAME2 = "CreaperTestFileAuditLog2"; + private static final Address TEST_FILE_AUDIT_LOG_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("file-audit-log", TEST_FILE_AUDIT_LOG_NAME2); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_FILE_AUDIT_LOG_ADDRESS); + ops.removeIfExists(TEST_FILE_AUDIT_LOG_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleFileAuditLog() throws Exception { + AddFileAuditLog addFileAuditLog = new AddFileAuditLog.Builder(TEST_FILE_AUDIT_LOG_NAME) + .path("audit.log") + .build(); + + client.apply(addFileAuditLog); + + assertTrue("File audit log should be created", ops.exists(TEST_FILE_AUDIT_LOG_ADDRESS)); + } + + @Test + public void addTwoFileAuditLogs() throws Exception { + AddFileAuditLog addFileAuditLog = new AddFileAuditLog.Builder(TEST_FILE_AUDIT_LOG_NAME) + .path("audit.log") + .build(); + AddFileAuditLog addFileAuditLog2 = new AddFileAuditLog.Builder(TEST_FILE_AUDIT_LOG_NAME2) + .path("audit.log") + .build(); + + client.apply(addFileAuditLog); + client.apply(addFileAuditLog2); + + assertTrue("File audit log should be created", ops.exists(TEST_FILE_AUDIT_LOG_ADDRESS)); + assertTrue("Second file audit log should be created", ops.exists(TEST_FILE_AUDIT_LOG_ADDRESS2)); + } + + @Test + public void addFullFileAuditLog() throws Exception { + AddFileAuditLog addFileAuditLog = new AddFileAuditLog.Builder(TEST_FILE_AUDIT_LOG_NAME) + .path("audit.log") + .format(AuditFormat.SIMPLE) + .paramSynchronized(false) + .relativeTo("jboss.server.log.dir") + .build(); + + client.apply(addFileAuditLog); + + assertTrue("File audit log should be created", ops.exists(TEST_FILE_AUDIT_LOG_ADDRESS)); + checkAttribute(TEST_FILE_AUDIT_LOG_ADDRESS, "path", "audit.log"); + checkAttribute(TEST_FILE_AUDIT_LOG_ADDRESS, "format", "SIMPLE"); + checkAttribute(TEST_FILE_AUDIT_LOG_ADDRESS, "synchronized", "false"); + checkAttribute(TEST_FILE_AUDIT_LOG_ADDRESS, "relative-to", "jboss.server.log.dir"); + } + + @Test(expected = CommandFailedException.class) + public void addExistFileAuditLogNotAllowed() throws Exception { + AddFileAuditLog addFileAuditLog = new AddFileAuditLog.Builder(TEST_FILE_AUDIT_LOG_NAME) + .path("audit.log") + .build(); + AddFileAuditLog addFileAuditLog2 = new AddFileAuditLog.Builder(TEST_FILE_AUDIT_LOG_NAME) + .path("audit.log") + .build(); + + client.apply(addFileAuditLog); + assertTrue("File audit log should be created", ops.exists(TEST_FILE_AUDIT_LOG_ADDRESS)); + client.apply(addFileAuditLog2); + fail("File audit log CreaperTestFileAuditLog already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistFileAuditLogAllowed() throws Exception { + AddFileAuditLog addFileAuditLog = new AddFileAuditLog.Builder(TEST_FILE_AUDIT_LOG_NAME) + .path("audit.log") + .build(); + AddFileAuditLog addFileAuditLog2 = new AddFileAuditLog.Builder(TEST_FILE_AUDIT_LOG_NAME) + .path("modified-audit.log") + .replaceExisting() + .build(); + + client.apply(addFileAuditLog); + assertTrue("File audit log should be created", ops.exists(TEST_FILE_AUDIT_LOG_ADDRESS)); + client.apply(addFileAuditLog2); + + // check whether it was really rewritten + checkAttribute(TEST_FILE_AUDIT_LOG_ADDRESS, "path", "modified-audit.log"); + } + + @Test(expected = IllegalArgumentException.class) + public void addFileAuditLog_nullName() throws Exception { + new AddFileAuditLog.Builder(null) + .path("audit.log") + .build(); + + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addFileAuditLog_emptyName() throws Exception { + new AddFileAuditLog.Builder("") + .path("audit.log") + .build(); + + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addFileAuditLog_nullPath() throws Exception { + new AddFileAuditLog.Builder(TEST_FILE_AUDIT_LOG_NAME) + .path(null) + .build(); + + fail("Creating command with null path should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addFileAuditLog_emptyPath() throws Exception { + new AddFileAuditLog.Builder(TEST_FILE_AUDIT_LOG_NAME) + .path("") + .build(); + + fail("Creating command with empty path should throw exception"); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/audit/AddPeriodicRotatingFileAuditLogOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/audit/AddPeriodicRotatingFileAuditLogOnlineTest.java new file mode 100644 index 00000000..afcc1821 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/audit/AddPeriodicRotatingFileAuditLogOnlineTest.java @@ -0,0 +1,192 @@ +package org.wildfly.extras.creaper.commands.elytron.audit; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddPeriodicRotatingFileAuditLogOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_NAME = "CreaperTestPeriodicRotatingFileAuditLog"; + private static final Address TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_ADDRESS = SUBSYSTEM_ADDRESS + .and("periodic-rotating-file-audit-log", TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_NAME); + private static final String TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_NAME2 + = "CreaperTestPeriodicRotatingFileAuditLog2"; + private static final Address TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("periodic-rotating-file-audit-log", TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_NAME2); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_ADDRESS); + ops.removeIfExists(TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addSimplePeriodicRotatingFileAuditLog() throws Exception { + AddPeriodicRotatingFileAuditLog addPeriodicRotatingFileAuditLog + = new AddPeriodicRotatingFileAuditLog.Builder(TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_NAME) + .path("audit.log") + .suffix("MM.dd") + .build(); + + client.apply(addPeriodicRotatingFileAuditLog); + + assertTrue("Periodic rotating file audit log should be created", + ops.exists(TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_ADDRESS)); + } + + @Test + public void addTwoPeriodicRotatingFileAuditLogs() throws Exception { + AddPeriodicRotatingFileAuditLog addPeriodicRotatingFileAuditLog + = new AddPeriodicRotatingFileAuditLog.Builder(TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_NAME) + .path("audit.log") + .suffix("MM.dd") + .build(); + AddPeriodicRotatingFileAuditLog addPeriodicRotatingFileAuditLog2 + = new AddPeriodicRotatingFileAuditLog.Builder(TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_NAME2) + .path("audit.log") + .suffix("MM.dd") + .build(); + + client.apply(addPeriodicRotatingFileAuditLog); + client.apply(addPeriodicRotatingFileAuditLog2); + + assertTrue("Periodic rotating file audit log should be created", + ops.exists(TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_ADDRESS)); + assertTrue("Second periodic rotating file audit log should be created", + ops.exists(TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_ADDRESS2)); + } + + @Test + public void addFullPeriodicRotatingFileAuditLog() throws Exception { + AddPeriodicRotatingFileAuditLog addPeriodicRotatingFileAuditLog + = new AddPeriodicRotatingFileAuditLog.Builder(TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_NAME) + .path("audit.log") + .format(AuditFormat.SIMPLE) + .paramSynchronized(false) + .relativeTo("jboss.server.log.dir") + .suffix("MM.dd") + .build(); + + client.apply(addPeriodicRotatingFileAuditLog); + + assertTrue("Periodic rotating file audit log should be created", + ops.exists(TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_ADDRESS)); + checkAttribute(TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_ADDRESS, "path", "audit.log"); + checkAttribute(TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_ADDRESS, "format", "SIMPLE"); + checkAttribute(TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_ADDRESS, "synchronized", "false"); + checkAttribute(TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_ADDRESS, "relative-to", "jboss.server.log.dir"); + checkAttribute(TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_ADDRESS, "suffix", "MM.dd"); + } + + @Test(expected = CommandFailedException.class) + public void addExistPeriodicRotatingFileAuditLogNotAllowed() throws Exception { + AddPeriodicRotatingFileAuditLog addPeriodicRotatingFileAuditLog + = new AddPeriodicRotatingFileAuditLog.Builder(TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_NAME) + .path("audit.log") + .suffix("MM.dd") + .build(); + AddPeriodicRotatingFileAuditLog addPeriodicRotatingFileAuditLog2 + = new AddPeriodicRotatingFileAuditLog.Builder(TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_NAME) + .path("audit.log") + .suffix("MM.dd") + .build(); + + client.apply(addPeriodicRotatingFileAuditLog); + assertTrue("Periodic rotating file audit log should be created", + ops.exists(TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_ADDRESS)); + client.apply(addPeriodicRotatingFileAuditLog2); + fail("Periodic rotating file audit log CreaperTestPeriodicRotatingFileAuditLog already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistPeriodicRotatingFileAuditLogAllowed() throws Exception { + AddPeriodicRotatingFileAuditLog addPeriodicRotatingFileAuditLog + = new AddPeriodicRotatingFileAuditLog.Builder(TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_NAME) + .path("audit.log") + .suffix("MM.dd") + .build(); + AddPeriodicRotatingFileAuditLog addPeriodicRotatingFileAuditLog2 + = new AddPeriodicRotatingFileAuditLog.Builder(TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_NAME) + .path("modified-audit.log") + .suffix("MM.dd") + .replaceExisting() + .build(); + + client.apply(addPeriodicRotatingFileAuditLog); + assertTrue("Periodic rotating file audit log should be created", + ops.exists(TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_ADDRESS)); + client.apply(addPeriodicRotatingFileAuditLog2); + + // check whether it was really rewritten + checkAttribute(TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_ADDRESS, "path", "modified-audit.log"); + } + + @Test(expected = IllegalArgumentException.class) + public void addPeriodicRotatingFileAuditLog_nullName() throws Exception { + new AddPeriodicRotatingFileAuditLog.Builder(null) + .path("audit.log") + .suffix("MM.dd") + .build(); + + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addPeriodicRotatingFileAuditLog_emptyName() throws Exception { + new AddPeriodicRotatingFileAuditLog.Builder("") + .path("audit.log") + .suffix("MM.dd") + .build(); + + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addPeriodicRotatingFileAuditLog_nullPath() throws Exception { + new AddPeriodicRotatingFileAuditLog.Builder(TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_NAME) + .path(null) + .suffix("MM.dd") + .build(); + + fail("Creating command with null path should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addPeriodicRotatingFileAuditLog_emptyPath() throws Exception { + new AddPeriodicRotatingFileAuditLog.Builder(TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_NAME) + .path("") + .suffix("MM.dd") + .build(); + + fail("Creating command with empty path should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addPeriodicRotatingFileAuditLog_nullSuffix() throws Exception { + new AddPeriodicRotatingFileAuditLog.Builder(TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_NAME) + .path("audit.log") + .suffix(null) + .build(); + + fail("Creating command with null suffix should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addPeriodicRotatingFileAuditLog_emptySuffix() throws Exception { + new AddPeriodicRotatingFileAuditLog.Builder(TEST_PERIODIC_ROTATING_FILE_AUDIT_LOG_NAME) + .path("audit.log") + .suffix("") + .build(); + + fail("Creating command with empty suffix should throw exception"); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/audit/AddSizeRotatingFileAuditLogOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/audit/AddSizeRotatingFileAuditLogOnlineTest.java new file mode 100644 index 00000000..0ffd35a9 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/audit/AddSizeRotatingFileAuditLogOnlineTest.java @@ -0,0 +1,166 @@ +package org.wildfly.extras.creaper.commands.elytron.audit; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddSizeRotatingFileAuditLogOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_SIZE_ROTATING_FILE_AUDIT_LOG_NAME = "CreaperTestSizeRotatingFileAuditLog"; + private static final Address TEST_SIZE_ROTATING_FILE_AUDIT_LOG_ADDRESS = SUBSYSTEM_ADDRESS + .and("size-rotating-file-audit-log", TEST_SIZE_ROTATING_FILE_AUDIT_LOG_NAME); + private static final String TEST_SIZE_ROTATING_FILE_AUDIT_LOG_NAME2 = "CreaperTestSizeRotatingFileAuditLog2"; + private static final Address TEST_SIZE_ROTATING_FILE_AUDIT_LOG_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("size-rotating-file-audit-log", TEST_SIZE_ROTATING_FILE_AUDIT_LOG_NAME2); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_SIZE_ROTATING_FILE_AUDIT_LOG_ADDRESS); + ops.removeIfExists(TEST_SIZE_ROTATING_FILE_AUDIT_LOG_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleSizeRotatingFileAuditLog() throws Exception { + AddSizeRotatingFileAuditLog addSizeRotatingFileAuditLog + = new AddSizeRotatingFileAuditLog.Builder(TEST_SIZE_ROTATING_FILE_AUDIT_LOG_NAME) + .path("audit.log") + .build(); + + client.apply(addSizeRotatingFileAuditLog); + + assertTrue("Size rotating file audit log should be created", + ops.exists(TEST_SIZE_ROTATING_FILE_AUDIT_LOG_ADDRESS)); + } + + @Test + public void addTwoSizeRotatingFileAuditLogs() throws Exception { + AddSizeRotatingFileAuditLog addSizeRotatingFileAuditLog + = new AddSizeRotatingFileAuditLog.Builder(TEST_SIZE_ROTATING_FILE_AUDIT_LOG_NAME) + .path("audit.log") + .build(); + AddSizeRotatingFileAuditLog addSizeRotatingFileAuditLog2 + = new AddSizeRotatingFileAuditLog.Builder(TEST_SIZE_ROTATING_FILE_AUDIT_LOG_NAME2) + .path("audit.log") + .build(); + + client.apply(addSizeRotatingFileAuditLog); + client.apply(addSizeRotatingFileAuditLog2); + + assertTrue("Size rotating file audit log should be created", + ops.exists(TEST_SIZE_ROTATING_FILE_AUDIT_LOG_ADDRESS)); + assertTrue("Second size rotating file audit log should be created", + ops.exists(TEST_SIZE_ROTATING_FILE_AUDIT_LOG_ADDRESS2)); + } + + @Test + public void addFullSizeRotatingFileAuditLog() throws Exception { + AddSizeRotatingFileAuditLog addSizeRotatingFileAuditLog + = new AddSizeRotatingFileAuditLog.Builder(TEST_SIZE_ROTATING_FILE_AUDIT_LOG_NAME) + .path("audit.log") + .format(AuditFormat.SIMPLE) + .paramSynchronized(false) + .relativeTo("jboss.server.log.dir") + .suffix("MM.dd") + .maxBackupIndex(10) + .rotateOnBoot(true) + .rotateSize("5M") + .build(); + + client.apply(addSizeRotatingFileAuditLog); + + assertTrue("Size rotating file audit log should be created", + ops.exists(TEST_SIZE_ROTATING_FILE_AUDIT_LOG_ADDRESS)); + checkAttribute(TEST_SIZE_ROTATING_FILE_AUDIT_LOG_ADDRESS, "path", "audit.log"); + checkAttribute(TEST_SIZE_ROTATING_FILE_AUDIT_LOG_ADDRESS, "format", "SIMPLE"); + checkAttribute(TEST_SIZE_ROTATING_FILE_AUDIT_LOG_ADDRESS, "synchronized", "false"); + checkAttribute(TEST_SIZE_ROTATING_FILE_AUDIT_LOG_ADDRESS, "relative-to", "jboss.server.log.dir"); + checkAttribute(TEST_SIZE_ROTATING_FILE_AUDIT_LOG_ADDRESS, "suffix", "MM.dd"); + checkAttribute(TEST_SIZE_ROTATING_FILE_AUDIT_LOG_ADDRESS, "max-backup-index", "10"); + checkAttribute(TEST_SIZE_ROTATING_FILE_AUDIT_LOG_ADDRESS, "rotate-on-boot", "true"); + checkAttribute(TEST_SIZE_ROTATING_FILE_AUDIT_LOG_ADDRESS, "rotate-size", "5M"); + } + + @Test(expected = CommandFailedException.class) + public void addExistSizeRotatingFileAuditLogNotAllowed() throws Exception { + AddSizeRotatingFileAuditLog addSizeRotatingFileAuditLog + = new AddSizeRotatingFileAuditLog.Builder(TEST_SIZE_ROTATING_FILE_AUDIT_LOG_NAME) + .path("audit.log") + .build(); + AddSizeRotatingFileAuditLog addSizeRotatingFileAuditLog2 + = new AddSizeRotatingFileAuditLog.Builder(TEST_SIZE_ROTATING_FILE_AUDIT_LOG_NAME) + .path("audit.log") + .build(); + + client.apply(addSizeRotatingFileAuditLog); + assertTrue("Size rotating file audit log should be created", + ops.exists(TEST_SIZE_ROTATING_FILE_AUDIT_LOG_ADDRESS)); + client.apply(addSizeRotatingFileAuditLog2); + fail("Size rotating file audit log CreaperTestSizeRotatingFileAuditLog already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistPeriodicRotatingFileAuditLogAllowed() throws Exception { + AddSizeRotatingFileAuditLog addSizeRotatingFileAuditLog + = new AddSizeRotatingFileAuditLog.Builder(TEST_SIZE_ROTATING_FILE_AUDIT_LOG_NAME) + .path("audit.log") + .build(); + AddSizeRotatingFileAuditLog addSizeRotatingFileAuditLog2 + = new AddSizeRotatingFileAuditLog.Builder(TEST_SIZE_ROTATING_FILE_AUDIT_LOG_NAME) + .path("modified-audit.log") + .replaceExisting() + .build(); + + client.apply(addSizeRotatingFileAuditLog); + assertTrue("Size rotating file audit log should be created", + ops.exists(TEST_SIZE_ROTATING_FILE_AUDIT_LOG_ADDRESS)); + client.apply(addSizeRotatingFileAuditLog2); + + // check whether it was really rewritten + checkAttribute(TEST_SIZE_ROTATING_FILE_AUDIT_LOG_ADDRESS, "path", "modified-audit.log"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSizeRotatingFileAuditLog_nullName() throws Exception { + new AddSizeRotatingFileAuditLog.Builder(null) + .path("audit.log") + .build(); + + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSizeRotatingFileAuditLog_emptyName() throws Exception { + new AddSizeRotatingFileAuditLog.Builder("") + .path("audit.log") + .build(); + + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSizeRotatingFileAuditLog_nullPath() throws Exception { + new AddSizeRotatingFileAuditLog.Builder(TEST_SIZE_ROTATING_FILE_AUDIT_LOG_NAME) + .path(null) + .build(); + + fail("Creating command with null path should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSizeRotatingFileAuditLog_emptyPath() throws Exception { + new AddSizeRotatingFileAuditLog.Builder(TEST_SIZE_ROTATING_FILE_AUDIT_LOG_NAME) + .path("") + .build(); + + fail("Creating command with empty path should throw exception"); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/audit/AddSyslogAuditLogOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/audit/AddSyslogAuditLogOnlineTest.java new file mode 100644 index 00000000..af18902c --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/audit/AddSyslogAuditLogOnlineTest.java @@ -0,0 +1,238 @@ +package org.wildfly.extras.creaper.commands.elytron.audit; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.commands.elytron.CredentialRef; +import org.wildfly.extras.creaper.commands.elytron.tls.AddClientSSLContext; +import org.wildfly.extras.creaper.commands.elytron.tls.AddKeyManager; +import org.wildfly.extras.creaper.commands.elytron.tls.AddKeyStore; + +@RunWith(Arquillian.class) +public class AddSyslogAuditLogOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_SYSLOG_AUDIT_LOG_NAME = "CreaperTestSyslogAuditLog"; + private static final Address TEST_SYSLOG_AUDIT_LOG_ADDRESS = SUBSYSTEM_ADDRESS + .and("syslog-audit-log", TEST_SYSLOG_AUDIT_LOG_NAME); + private static final String TEST_SYSLOG_AUDIT_LOG_NAME2 = "CreaperTestSyslogAuditLog2"; + private static final Address TEST_SYSLOG_AUDIT_LOG_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("syslog-audit-log", TEST_SYSLOG_AUDIT_LOG_NAME2); + + private static final String TEST_CLIENT_SSL_CONTEXT_NAME = "CreaperTestSslContext"; + private static final Address TEST_CLIENT_SSL_CONTEXT_ADDRESS = SUBSYSTEM_ADDRESS + .and("client-ssl-context", TEST_CLIENT_SSL_CONTEXT_NAME); + private static final String TEST_KEY_STORE_NAME = "CreaperTestKeyStore"; + private static final Address TEST_KEY_STORE_NAME_ADDRESS = SUBSYSTEM_ADDRESS + .and("key-store", TEST_KEY_STORE_NAME); + private static final String TEST_KEY_MNGR_NAME = "CreaperTestKeyManager"; + private static final Address TEST_KEY_MNGR_NAME_ADDRESS = SUBSYSTEM_ADDRESS + .and("key-manager", TEST_KEY_MNGR_NAME); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_SYSLOG_AUDIT_LOG_ADDRESS); + ops.removeIfExists(TEST_SYSLOG_AUDIT_LOG_ADDRESS2); + ops.removeIfExists(TEST_CLIENT_SSL_CONTEXT_ADDRESS); + ops.removeIfExists(TEST_KEY_MNGR_NAME_ADDRESS); + ops.removeIfExists(TEST_KEY_STORE_NAME_ADDRESS); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleSyslogAuditLog() throws Exception { + AddSyslogAuditLog addSyslogAuditLog = new AddSyslogAuditLog.Builder(TEST_SYSLOG_AUDIT_LOG_NAME) + .serverAddress("localhost") + .port(9898) + .hostName("Elytron-audit") + .build(); + + client.apply(addSyslogAuditLog); + + assertTrue("Syslog audit log should be created", ops.exists(TEST_SYSLOG_AUDIT_LOG_ADDRESS)); + } + + @Test + public void addTwoSyslogAuditLogs() throws Exception { + AddSyslogAuditLog addSyslogAuditLog = new AddSyslogAuditLog.Builder(TEST_SYSLOG_AUDIT_LOG_NAME) + .serverAddress("localhost") + .port(9898) + .hostName("Elytron-audit") + .build(); + AddSyslogAuditLog addSyslogAuditLog2 = new AddSyslogAuditLog.Builder(TEST_SYSLOG_AUDIT_LOG_NAME2) + .serverAddress("localhost") + .port(9898) + .hostName("Elytron-audit") + .build(); + + client.apply(addSyslogAuditLog); + client.apply(addSyslogAuditLog2); + + assertTrue("Syslog audit log should be created", ops.exists(TEST_SYSLOG_AUDIT_LOG_ADDRESS)); + assertTrue("Second syslog audit log should be created", ops.exists(TEST_SYSLOG_AUDIT_LOG_ADDRESS2)); + } + + @Test + public void addFullSyslogAuditLog() throws Exception { + AddKeyStore addKeyStore = new AddKeyStore.Builder(TEST_KEY_STORE_NAME) + .type("JKS") + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("password") + .build()) + .build(); + client.apply(addKeyStore); + AddKeyManager addKeyManager = new AddKeyManager.Builder(TEST_KEY_MNGR_NAME) + .keyStore(TEST_KEY_STORE_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("password") + .build()) + .build(); + client.apply(addKeyManager); + AddClientSSLContext addClientSSLContext = new AddClientSSLContext.Builder(TEST_CLIENT_SSL_CONTEXT_NAME) + .keyManager(TEST_KEY_MNGR_NAME) + .build(); + client.apply(addClientSSLContext); + + AddSyslogAuditLog addSyslogAuditLog = new AddSyslogAuditLog.Builder(TEST_SYSLOG_AUDIT_LOG_NAME) + .serverAddress("localhost") + .port(9898) + .hostName("Elytron-audit") + .format(AuditFormat.JSON) + .transport(AddSyslogAuditLog.TransportProtocolType.UDP) + .sslContext(TEST_CLIENT_SSL_CONTEXT_NAME) + .build(); + + client.apply(addSyslogAuditLog); + + assertTrue("Syslog audit log should be created", ops.exists(TEST_SYSLOG_AUDIT_LOG_ADDRESS)); + checkAttribute(TEST_SYSLOG_AUDIT_LOG_ADDRESS, "server-address", "localhost"); + checkAttribute(TEST_SYSLOG_AUDIT_LOG_ADDRESS, "port", "9898"); + checkAttribute(TEST_SYSLOG_AUDIT_LOG_ADDRESS, "host-name", "Elytron-audit"); + checkAttribute(TEST_SYSLOG_AUDIT_LOG_ADDRESS, "format", "JSON"); + checkAttribute(TEST_SYSLOG_AUDIT_LOG_ADDRESS, "transport", "UDP"); + checkAttribute(TEST_SYSLOG_AUDIT_LOG_ADDRESS, "ssl-context", TEST_CLIENT_SSL_CONTEXT_NAME); + } + + @Test(expected = CommandFailedException.class) + public void addExistSyslogAuditLogNotAllowed() throws Exception { + AddSyslogAuditLog addSyslogAuditLog = new AddSyslogAuditLog.Builder(TEST_SYSLOG_AUDIT_LOG_NAME) + .serverAddress("localhost") + .port(9898) + .hostName("Elytron-audit") + .build(); + AddSyslogAuditLog addSyslogAuditLog2 = new AddSyslogAuditLog.Builder(TEST_SYSLOG_AUDIT_LOG_NAME) + .serverAddress("localhost") + .port(9898) + .hostName("Elytron-audit") + .build(); + + client.apply(addSyslogAuditLog); + assertTrue("Syslog audit log should be created", ops.exists(TEST_SYSLOG_AUDIT_LOG_ADDRESS)); + client.apply(addSyslogAuditLog2); + fail("Syslog audit log CreaperTestSyslogAuditLog already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistSyslogAuditLogAllowed() throws Exception { + AddSyslogAuditLog addSyslogAuditLog = new AddSyslogAuditLog.Builder(TEST_SYSLOG_AUDIT_LOG_NAME) + .serverAddress("localhost") + .port(9898) + .hostName("Elytron-audit") + .build(); + AddSyslogAuditLog addSyslogAuditLog2 = new AddSyslogAuditLog.Builder(TEST_SYSLOG_AUDIT_LOG_NAME) + .serverAddress("localhost") + .port(9898) + .hostName("another-hostname") + .replaceExisting() + .build(); + + client.apply(addSyslogAuditLog); + assertTrue("Syslog audit log should be created", ops.exists(TEST_SYSLOG_AUDIT_LOG_ADDRESS)); + client.apply(addSyslogAuditLog2); + + // check whether it was really rewritten + checkAttribute(TEST_SYSLOG_AUDIT_LOG_ADDRESS, "host-name", "another-hostname"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSyslogAuditLog_nullName() throws Exception { + new AddSyslogAuditLog.Builder(null) + .serverAddress("localhost") + .port(9898) + .hostName("Elytron-audit") + .build(); + + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSyslogAuditLog_emptyName() throws Exception { + new AddSyslogAuditLog.Builder("") + .serverAddress("localhost") + .port(9898) + .hostName("Elytron-audit") + .build(); + + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSyslogAuditLog_nullServerAddress() throws Exception { + new AddSyslogAuditLog.Builder(TEST_SYSLOG_AUDIT_LOG_NAME) + .serverAddress(null) + .port(9898) + .hostName("Elytron-audit") + .build(); + + fail("Creating command with null server-address should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSyslogAuditLog_emptyServerAddress() throws Exception { + new AddSyslogAuditLog.Builder(TEST_SYSLOG_AUDIT_LOG_NAME) + .serverAddress("") + .port(9898) + .hostName("Elytron-audit") + .build(); + + fail("Creating command with empty server-address should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSyslogAuditLog_undefinedPort() throws Exception { + new AddSyslogAuditLog.Builder(TEST_SYSLOG_AUDIT_LOG_NAME) + .serverAddress("localhost") + .hostName("Elytron-audit") + .build(); + + fail("Creating command with undefined port should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSyslogAuditLog_nullHostName() throws Exception { + new AddSyslogAuditLog.Builder(TEST_SYSLOG_AUDIT_LOG_NAME) + .serverAddress("localhost") + .port(9898) + .hostName(null) + .build(); + + fail("Creating command with null host-name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSyslogAuditLog_emptyHostName() throws Exception { + new AddSyslogAuditLog.Builder(TEST_SYSLOG_AUDIT_LOG_NAME) + .serverAddress("localhost") + .port(9898) + .hostName("") + .build(); + + fail("Creating command with empty host-name should throw exception"); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/authenticationclient/AddAuthenticationConfigurationOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/authenticationclient/AddAuthenticationConfigurationOnlineTest.java new file mode 100644 index 00000000..70a3224c --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/authenticationclient/AddAuthenticationConfigurationOnlineTest.java @@ -0,0 +1,357 @@ +package org.wildfly.extras.creaper.commands.elytron.authenticationclient; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.commands.elytron.CredentialRef; +import org.wildfly.extras.creaper.commands.elytron.Property; +import org.wildfly.extras.creaper.commands.elytron.credfactory.AddKerberosSecurityFactory; +import org.wildfly.extras.creaper.commands.elytron.domain.AddSecurityDomain; +import org.wildfly.extras.creaper.commands.elytron.realm.AddFilesystemRealm; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddAuthenticationConfigurationOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_AUTHENTICATION_CONFIGURATION_NAME = "CreaperTestAuthenticationConfiguration"; + private static final Address TEST_AUTHENTICATION_CONFIGURATION_ADDRESS = SUBSYSTEM_ADDRESS + .and("authentication-configuration", TEST_AUTHENTICATION_CONFIGURATION_NAME); + private static final String TEST_AUTHENTICATION_CONFIGURATION_NAME2 = "CreaperTestAuthenticationConfiguration2"; + private static final Address TEST_AUTHENTICATION_CONFIGURATION_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("authentication-configuration", TEST_AUTHENTICATION_CONFIGURATION_NAME2); + + private static final String TEST_SECURITY_DOMAIN_NAME = "CreaperTestSecurityDomain"; + private static final Address TEST_SECURITY_DOMAIN_ADDRESS = SUBSYSTEM_ADDRESS + .and("security-domain", TEST_SECURITY_DOMAIN_NAME); + private static final String TEST_FILESYSTEM_REALM_NAME = "CreaperTestFilesystemRealm"; + private static final Address TEST_FILESYSTEM_REALM_ADDRESS = SUBSYSTEM_ADDRESS + .and("filesystem-realm", TEST_FILESYSTEM_REALM_NAME); + private final AddFilesystemRealm addFilesystemRealm = new AddFilesystemRealm.Builder(TEST_FILESYSTEM_REALM_NAME) + .path("/path/to/filesystem") + .build(); + + private static final String TEST_KRB_FACTORY_NAME = "CreaperTestFilesystemRealm"; + private static final Address TEST_KRB_FACTORY_ADDRESS = SUBSYSTEM_ADDRESS + .and("kerberos-security-factory", TEST_KRB_FACTORY_NAME); + private final AddKerberosSecurityFactory addKerberosSecurityFactory + = new AddKerberosSecurityFactory.Builder(TEST_KRB_FACTORY_NAME) + .principal("somePrincipal") + .path("/some/path") + .build(); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_AUTHENTICATION_CONFIGURATION_ADDRESS); + ops.removeIfExists(TEST_AUTHENTICATION_CONFIGURATION_ADDRESS2); + ops.removeIfExists(TEST_SECURITY_DOMAIN_ADDRESS); + ops.removeIfExists(TEST_FILESYSTEM_REALM_ADDRESS); + ops.removeIfExists(TEST_KRB_FACTORY_ADDRESS); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleAuthenticationConfiguration() throws Exception { + AddAuthenticationConfiguration addAuthenticationConfiguration + = new AddAuthenticationConfiguration.Builder(TEST_AUTHENTICATION_CONFIGURATION_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("somePassword") + .build()) + .build(); + + client.apply(addAuthenticationConfiguration); + + assertTrue("Authentication Configuration should be created", + ops.exists(TEST_AUTHENTICATION_CONFIGURATION_ADDRESS)); + } + + @Test + public void addTwoAuthenticationConfigurations() throws Exception { + AddAuthenticationConfiguration addAuthenticationConfiguration + = new AddAuthenticationConfiguration.Builder(TEST_AUTHENTICATION_CONFIGURATION_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("somePassword") + .build()) + .build(); + + AddAuthenticationConfiguration addAuthenticationConfiguration2 + = new AddAuthenticationConfiguration.Builder(TEST_AUTHENTICATION_CONFIGURATION_NAME2) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("somePassword") + .build()) + .build(); + + client.apply(addAuthenticationConfiguration); + client.apply(addAuthenticationConfiguration2); + + assertTrue("Authentication Configuration should be created", + ops.exists(TEST_AUTHENTICATION_CONFIGURATION_ADDRESS)); + assertTrue("Second Authentication Configuration should be created", + ops.exists(TEST_AUTHENTICATION_CONFIGURATION_ADDRESS2)); + } + + @Test + public void addFullAuthenticationConfiguration() throws Exception { + AddAuthenticationConfiguration addAuthenticationConfiguration2 + = new AddAuthenticationConfiguration.Builder(TEST_AUTHENTICATION_CONFIGURATION_NAME2) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("somePassword2") + .build()) + .build(); + client.apply(addAuthenticationConfiguration2); + + AddAuthenticationConfiguration addAuthenticationConfiguration + = new AddAuthenticationConfiguration.Builder(TEST_AUTHENTICATION_CONFIGURATION_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("somePassword") + .build()) + .addMechanismProperties(new Property("property1", "value1"), + new Property("property2", "value2")) + .extend(TEST_AUTHENTICATION_CONFIGURATION_NAME2) + .authenticationName("someAuthenticationName") + .authorizationName("someAuthorizationName") + .host("someHost") + .protocol("someProtocol") + .port(12345) + .realm("someRealm") + .forwardingMode(AddAuthenticationConfiguration.ForwardingMode.AUTHORIZATION) + .build(); + client.apply(addAuthenticationConfiguration); + + assertTrue("Authentication Configuration should be created", + ops.exists(TEST_AUTHENTICATION_CONFIGURATION_ADDRESS)); + + checkAttribute("extends", TEST_AUTHENTICATION_CONFIGURATION_NAME2); + checkAttribute("authentication-name", "someAuthenticationName"); + checkAttribute("authorization-name", "someAuthorizationName"); + checkAttribute("host", "someHost"); + checkAttribute("protocol", "someProtocol"); + checkAttribute("port", "12345"); + checkAttribute("realm", "someRealm"); + checkAttribute("credential-reference.clear-text", "somePassword"); + checkAttribute("forwarding-mode", "authorization"); + checkAttribute("mechanism-properties.property1", "value1"); + checkAttribute("mechanism-properties.property2", "value2"); + } + + @Test + public void addAuthenticationConfiguration_anonymous() throws Exception { + AddAuthenticationConfiguration addAuthenticationConfiguration + = new AddAuthenticationConfiguration.Builder(TEST_AUTHENTICATION_CONFIGURATION_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("somePassword") + .build()) + .anonymous(false) + .build(); + client.apply(addAuthenticationConfiguration); + + assertTrue("Authentication Configuration should be created", + ops.exists(TEST_AUTHENTICATION_CONFIGURATION_ADDRESS)); + + checkAttribute("anonymous", "false"); + } + + @Test + public void addAuthenticationConfiguration_securityDomain() throws Exception { + client.apply(addFilesystemRealm); + + AddSecurityDomain addSecurityDomain = new AddSecurityDomain.Builder(TEST_SECURITY_DOMAIN_NAME) + .defaultRealm(TEST_FILESYSTEM_REALM_NAME) + .realms(new AddSecurityDomain.RealmBuilder(TEST_FILESYSTEM_REALM_NAME) + .build()) + .build(); + client.apply(addSecurityDomain); + + AddAuthenticationConfiguration addAuthenticationConfiguration + = new AddAuthenticationConfiguration.Builder(TEST_AUTHENTICATION_CONFIGURATION_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("somePassword") + .build()) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .build(); + client.apply(addAuthenticationConfiguration); + + assertTrue("Authentication Configuration should be created", + ops.exists(TEST_AUTHENTICATION_CONFIGURATION_ADDRESS)); + + checkAttribute("security-domain", TEST_SECURITY_DOMAIN_NAME); + } + + @Test + public void addAuthenticationConfiguration_kerberosSecurityFactory() throws Exception { + client.apply(addFilesystemRealm); + client.apply(addKerberosSecurityFactory); + + AddAuthenticationConfiguration addAuthenticationConfiguration + = new AddAuthenticationConfiguration.Builder(TEST_AUTHENTICATION_CONFIGURATION_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("somePassword") + .build()) + .kerberosSecurityFactory(TEST_KRB_FACTORY_NAME) + .build(); + client.apply(addAuthenticationConfiguration); + + assertTrue("Authentication Configuration should be created", + ops.exists(TEST_AUTHENTICATION_CONFIGURATION_ADDRESS)); + + checkAttribute("kerberos-security-factory", TEST_KRB_FACTORY_NAME); + } + + @Test(expected = CommandFailedException.class) + public void addExistAuthenticationConfigurationNotAllowed() throws Exception { + AddAuthenticationConfiguration addAuthenticationConfiguration + = new AddAuthenticationConfiguration.Builder(TEST_AUTHENTICATION_CONFIGURATION_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("somePassword") + .build()) + .host("someHost1") + .build(); + + AddAuthenticationConfiguration addAuthenticationConfiguration2 + = new AddAuthenticationConfiguration.Builder(TEST_AUTHENTICATION_CONFIGURATION_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("somePassword") + .build()) + .host("someHost2") + .build(); + + client.apply(addAuthenticationConfiguration); + assertTrue("Authentication Configuration should be created", + ops.exists(TEST_AUTHENTICATION_CONFIGURATION_ADDRESS)); + client.apply(addAuthenticationConfiguration2); + fail("Authentication Configuration CreaperTestAuthenticationConfiguration already exists in configuration, exception should be thrown"); + + } + + @Test + public void addExistAuthenticationConfigurationAllowed() throws Exception { + AddAuthenticationConfiguration addAuthenticationConfiguration + = new AddAuthenticationConfiguration.Builder(TEST_AUTHENTICATION_CONFIGURATION_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("somePassword") + .build()) + .host("someHost1") + .build(); + + AddAuthenticationConfiguration addAuthenticationConfiguration2 + = new AddAuthenticationConfiguration.Builder(TEST_AUTHENTICATION_CONFIGURATION_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("somePassword") + .build()) + .host("someHost2") + .replaceExisting() + .build(); + + client.apply(addAuthenticationConfiguration); + assertTrue("Authentication Configuration should be created", + ops.exists(TEST_AUTHENTICATION_CONFIGURATION_ADDRESS)); + client.apply(addAuthenticationConfiguration2); + assertTrue("Authentication Configuration should be created", + ops.exists(TEST_AUTHENTICATION_CONFIGURATION_ADDRESS)); + checkAttribute("host", "someHost2"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAuthenticationConfiguration_nullName() throws Exception { + new AddAuthenticationConfiguration.Builder(null) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("somePassword") + .build()) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAuthenticationConfiguration_emptyName() throws Exception { + new AddAuthenticationConfiguration.Builder("") + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("somePassword") + .build()) + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAuthenticationConfiguration_authenticationNameAndAnonymous() throws Exception { + new AddAuthenticationConfiguration.Builder(TEST_AUTHENTICATION_CONFIGURATION_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("somePassword") + .build()) + .authenticationName("someAuthenticationName") + .anonymous(true) + .build(); + fail("Creating command with both authenticationName and anonymous should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAuthenticationConfiguration_authenticationNameAndSecurityDomain() throws Exception { + new AddAuthenticationConfiguration.Builder(TEST_AUTHENTICATION_CONFIGURATION_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("somePassword") + .build()) + .authenticationName("someAuthenticationName") + .securityDomain("someSecurityDomain") + .build(); + fail("Creating command with both authenticationName and securityDomain should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAuthenticationConfiguration_anonymousAndSecurityDomain() throws Exception { + new AddAuthenticationConfiguration.Builder(TEST_AUTHENTICATION_CONFIGURATION_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("somePassword") + .build()) + .anonymous(true) + .securityDomain("someSecurityDomain") + .build(); + fail("Creating command with both anonymous and securityDomain should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAuthenticationConfiguration_anonymousAndKerberosSecurityFactory() throws Exception { + new AddAuthenticationConfiguration.Builder(TEST_AUTHENTICATION_CONFIGURATION_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("somePassword") + .build()) + .anonymous(true) + .kerberosSecurityFactory("someKerberosSecurityFactory") + .build(); + fail("Creating command with both anonymous and kerberosSecurityFactory should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAuthenticationConfiguration_authenticationNameAndKerberosSecurityFactory() throws Exception { + new AddAuthenticationConfiguration.Builder(TEST_AUTHENTICATION_CONFIGURATION_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("somePassword") + .build()) + .authenticationName("someAuthenticationName") + .kerberosSecurityFactory("someKerberosSecurityFactory") + .build(); + fail("Creating command with both authenticationName and kerberosSecurityFactory should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAuthenticationConfiguration_securityDomainAndKerberosSecurityFactory() throws Exception { + new AddAuthenticationConfiguration.Builder(TEST_AUTHENTICATION_CONFIGURATION_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("somePassword") + .build()) + .securityDomain("someSecurityDomain") + .kerberosSecurityFactory("someKerberosSecurityFactory") + .build(); + fail("Creating command with both securityDomain and kerberosSecurityFactory should throw exception"); + } + + private void checkAttribute(String attribute, String expectedValue) throws IOException { + checkAttribute(TEST_AUTHENTICATION_CONFIGURATION_ADDRESS, attribute, expectedValue); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/authenticationclient/AddAuthenticationContextOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/authenticationclient/AddAuthenticationContextOnlineTest.java new file mode 100644 index 00000000..31653f0c --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/authenticationclient/AddAuthenticationContextOnlineTest.java @@ -0,0 +1,244 @@ +package org.wildfly.extras.creaper.commands.elytron.authenticationclient; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.commands.elytron.CredentialRef; +import org.wildfly.extras.creaper.commands.elytron.tls.AddKeyManager; +import org.wildfly.extras.creaper.commands.elytron.tls.AddKeyStore; +import org.wildfly.extras.creaper.commands.elytron.tls.AddServerSSLContext; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddAuthenticationContextOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_AUTHENTICATION_CONTEXT_NAME = "CreaperTestAuthenticationContext"; + private static final Address TEST_AUTHENTICATION_CONTEXT_ADDRESS = SUBSYSTEM_ADDRESS + .and("authentication-context", TEST_AUTHENTICATION_CONTEXT_NAME); + private static final String TEST_AUTHENTICATION_CONTEXT_NAME2 = "CreaperTestAuthenticationContext2"; + private static final Address TEST_AUTHENTICATION_CONTEXT_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("authentication-context", TEST_AUTHENTICATION_CONTEXT_NAME2); + + private static final String TEST_AUTHENTICATION_CONFIGURATION_NAME = "CreaperTestAuthenticationConfiguration"; + private static final Address TEST_AUTHENTICATION_CONFIGURATION_ADDRESS = SUBSYSTEM_ADDRESS + .and("authentication-configuration", TEST_AUTHENTICATION_CONFIGURATION_NAME); + + private static final String TEST_SERVER_SSL_CONTEXT_NAME = "CreaperTestSslContext"; + private static final Address TEST_SERVER_SSL_CONTEXT_ADDRESS = SUBSYSTEM_ADDRESS + .and("server-ssl-context", TEST_SERVER_SSL_CONTEXT_NAME); + + private static final String TEST_KEY_STORE_NAME = "CreaperTestKeyStore"; + private static final Address TEST_KEY_STORE_NAME_ADDRESS = SUBSYSTEM_ADDRESS + .and("key-store", TEST_KEY_STORE_NAME); + private static final String TEST_KEY_STORE_TYPE = "JKS"; + private static final String TEST_KEY_STORE_PASSWORD = "password"; + private static final String TEST_KEY_PASSWORD = "password"; + private static final String TEST_KEY_MNGR_NAME = "CreaperTestKeyManager"; + private static final Address TEST_KEY_MNGR_NAME_ADDRESS = SUBSYSTEM_ADDRESS + .and("key-manager", TEST_KEY_MNGR_NAME); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_AUTHENTICATION_CONTEXT_ADDRESS); + ops.removeIfExists(TEST_AUTHENTICATION_CONTEXT_ADDRESS2); + ops.removeIfExists(TEST_AUTHENTICATION_CONFIGURATION_ADDRESS); + ops.removeIfExists(TEST_SERVER_SSL_CONTEXT_ADDRESS); + ops.removeIfExists(TEST_KEY_MNGR_NAME_ADDRESS); + ops.removeIfExists(TEST_KEY_STORE_NAME_ADDRESS); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleAuthenticationContext() throws Exception { + AddAuthenticationContext addAuthenticationContext + = new AddAuthenticationContext.Builder(TEST_AUTHENTICATION_CONTEXT_NAME) + .build(); + + client.apply(addAuthenticationContext); + + assertTrue("Authentication Context should be created", ops.exists(TEST_AUTHENTICATION_CONTEXT_ADDRESS)); + } + + @Test + public void addTwoAuthenticationContexts() throws Exception { + AddAuthenticationContext addAuthenticationContext + = new AddAuthenticationContext.Builder(TEST_AUTHENTICATION_CONTEXT_NAME) + .build(); + + AddAuthenticationContext addAuthenticationContext2 + = new AddAuthenticationContext.Builder(TEST_AUTHENTICATION_CONTEXT_NAME2) + .build(); + + client.apply(addAuthenticationContext); + client.apply(addAuthenticationContext2); + + assertTrue("Authentication Context should be created", ops.exists(TEST_AUTHENTICATION_CONTEXT_ADDRESS)); + assertTrue("Second Authentication Context should be created", + ops.exists(TEST_AUTHENTICATION_CONTEXT_ADDRESS2)); + } + + @Test + public void addFullAuthenticationContext() throws Exception { + AddAuthenticationConfiguration addAuthenticationConfiguration + = new AddAuthenticationConfiguration.Builder(TEST_AUTHENTICATION_CONFIGURATION_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("somePassword") + .build()) + .build(); + client.apply(addAuthenticationConfiguration); + + AddAuthenticationContext addAuthenticationContext2 + = new AddAuthenticationContext.Builder(TEST_AUTHENTICATION_CONTEXT_NAME2) + .build(); + client.apply(addAuthenticationContext2); + + AddKeyStore addKeyStore = new AddKeyStore.Builder(TEST_KEY_STORE_NAME) + .type(TEST_KEY_STORE_TYPE) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_STORE_PASSWORD) + .build()) + .build(); + client.apply(addKeyStore); + AddKeyManager addKeyManager = new AddKeyManager.Builder(TEST_KEY_MNGR_NAME) + .keyStore(TEST_KEY_STORE_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_PASSWORD) + .build()) + .build(); + client.apply(addKeyManager); + + AddServerSSLContext addServerSSLContext = new AddServerSSLContext.Builder(TEST_SERVER_SSL_CONTEXT_NAME) + .keyManager(TEST_KEY_MNGR_NAME) + .build(); + client.apply(addServerSSLContext); + + AddAuthenticationContext addAuthenticationContext + = new AddAuthenticationContext.Builder(TEST_AUTHENTICATION_CONTEXT_NAME) + .extend(TEST_AUTHENTICATION_CONTEXT_NAME2) + .addMatchRules(new AddAuthenticationContext.MatchRuleBuilder() + .authenticationConfiguration(TEST_AUTHENTICATION_CONFIGURATION_NAME) + .sslContext(TEST_SERVER_SSL_CONTEXT_NAME) + .matchAbstractType("someAbstractType1") + .matchAbstractTypeAuthority("someAbstractTypeAuthority1") + .matchHost("someHost1") + .matchLocalSecurityDomain("someLocalSecurityDomain1") + .matchNoUser(true) + .matchPath("somePath1") + .matchPort(12345) + .matchProtocol("someProtocol1") + .matchUrn("someUrn1") + .build(), + new AddAuthenticationContext.MatchRuleBuilder() + .authenticationConfiguration(TEST_AUTHENTICATION_CONFIGURATION_NAME) + .sslContext(TEST_SERVER_SSL_CONTEXT_NAME) + .matchAbstractType("someAbstractType2") + .matchAbstractTypeAuthority("someAbstractTypeAuthority2") + .matchHost("someHost2") + .matchLocalSecurityDomain("someLocalSecurityDomain2") + .matchPath("somePath2") + .matchPort(12346) + .matchProtocol("someProtocol2") + .matchUrn("someUrn2") + .matchUser("someUser2") + .build()) + .build(); + client.apply(addAuthenticationContext); + + assertTrue("Authentication Context should be created", ops.exists(TEST_AUTHENTICATION_CONTEXT_ADDRESS)); + + checkAttribute("extends", TEST_AUTHENTICATION_CONTEXT_NAME2); + checkAttribute("match-rules[0].authentication-configuration", TEST_AUTHENTICATION_CONFIGURATION_NAME); + checkAttribute("match-rules[0].ssl-context", TEST_SERVER_SSL_CONTEXT_NAME); + checkAttribute("match-rules[0].match-abstract-type", "someAbstractType1"); + checkAttribute("match-rules[0].match-abstract-type-authority", "someAbstractTypeAuthority1"); + checkAttribute("match-rules[0].match-host", "someHost1"); + checkAttribute("match-rules[0].match-local-security-domain", "someLocalSecurityDomain1"); + checkAttribute("match-rules[0].match-no-user", "true"); + checkAttribute("match-rules[0].match-path", "somePath1"); + checkAttribute("match-rules[0].match-port", "12345"); + checkAttribute("match-rules[0].match-protocol", "someProtocol1"); + checkAttribute("match-rules[0].match-urn", "someUrn1"); + checkAttribute("match-rules[1].authentication-configuration", TEST_AUTHENTICATION_CONFIGURATION_NAME); + checkAttribute("match-rules[1].ssl-context", TEST_SERVER_SSL_CONTEXT_NAME); + checkAttribute("match-rules[1].match-abstract-type", "someAbstractType2"); + checkAttribute("match-rules[1].match-abstract-type-authority", "someAbstractTypeAuthority2"); + checkAttribute("match-rules[1].match-host", "someHost2"); + checkAttribute("match-rules[1].match-local-security-domain", "someLocalSecurityDomain2"); + checkAttribute("match-rules[1].match-path", "somePath2"); + checkAttribute("match-rules[1].match-port", "12346"); + checkAttribute("match-rules[1].match-protocol", "someProtocol2"); + checkAttribute("match-rules[1].match-urn", "someUrn2"); + checkAttribute("match-rules[1].match-user", "someUser2"); + } + + @Test(expected = CommandFailedException.class) + public void addExistAuthenticationContextNotAllowed() throws Exception { + AddAuthenticationContext addAuthenticationContext + = new AddAuthenticationContext.Builder(TEST_AUTHENTICATION_CONTEXT_NAME) + .addMatchRules(new AddAuthenticationContext.MatchRuleBuilder() + .matchHost("someHost1") + .build()) + .build(); + + AddAuthenticationContext addAuthenticationContext2 + = new AddAuthenticationContext.Builder(TEST_AUTHENTICATION_CONTEXT_NAME) + .addMatchRules(new AddAuthenticationContext.MatchRuleBuilder() + .matchHost("someHost2") + .build()) + .build(); + + client.apply(addAuthenticationContext); + assertTrue("Authentication Context should be created", ops.exists(TEST_AUTHENTICATION_CONTEXT_ADDRESS)); + client.apply(addAuthenticationContext2); + fail("Authentication Context CreaperTestAuthenticationContext already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistAuthenticationContextAllowed() throws Exception { + AddAuthenticationContext addAuthenticationContext + = new AddAuthenticationContext.Builder(TEST_AUTHENTICATION_CONTEXT_NAME) + .addMatchRules(new AddAuthenticationContext.MatchRuleBuilder() + .matchHost("someHost1") + .build()) + .build(); + + AddAuthenticationContext addAuthenticationContext2 + = new AddAuthenticationContext.Builder(TEST_AUTHENTICATION_CONTEXT_NAME) + .addMatchRules(new AddAuthenticationContext.MatchRuleBuilder() + .matchHost("someHost2") + .build()) + .replaceExisting() + .build(); + + client.apply(addAuthenticationContext); + assertTrue("Authentication Context should be created", ops.exists(TEST_AUTHENTICATION_CONTEXT_ADDRESS)); + client.apply(addAuthenticationContext2); + checkAttribute("match-rules[0].match-host", "someHost2"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAuthenticationContext_nullName() throws Exception { + new AddAuthenticationContext.Builder(null) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAuthenticationContext_emptyName() throws Exception { + new AddAuthenticationContext.Builder("") + .build(); + fail("Creating command with empty name should throw exception"); + } + + private void checkAttribute(String attribute, String expectedValue) throws IOException { + checkAttribute(TEST_AUTHENTICATION_CONTEXT_ADDRESS, attribute, expectedValue); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/AbstractCredentialStoreOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/AbstractCredentialStoreOnlineTest.java new file mode 100644 index 00000000..3ba94353 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/AbstractCredentialStoreOnlineTest.java @@ -0,0 +1,56 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2017, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.wildfly.extras.creaper.commands.elytron.credentialstore; + +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.List; + +import org.jboss.dmr.ModelNode; +import org.junit.Assert; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.online.ModelNodeResult; +import org.wildfly.extras.creaper.core.online.operations.Address; + +public class AbstractCredentialStoreOnlineTest extends AbstractElytronOnlineTest { + + protected boolean aliasExists(Address credentialStore, String alias) throws IOException { + Assert.assertNotNull(alias); + ModelNodeResult result = ops.invoke("read-aliases", credentialStore); + assertTrue("read-aliases operation must be successful.", result.isSuccess()); + ModelNode modelNode = result.value(); + if (!result.isSuccess() || modelNode.asList().isEmpty()) { + return false; + } + List aliasList = modelNode.asList(); + for (ModelNode aliasName : aliasList) { + if (alias.equals(aliasName.asString())) { + return true; + } + } + + return false; + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/AddCredentialStoreAliasOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/AddCredentialStoreAliasOnlineTest.java new file mode 100644 index 00000000..1e6a38da --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/AddCredentialStoreAliasOnlineTest.java @@ -0,0 +1,257 @@ +package org.wildfly.extras.creaper.commands.elytron.credentialstore; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.CredentialRef; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.OnlineManagementClient; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; + +@RunWith(Arquillian.class) +public class AddCredentialStoreAliasOnlineTest extends AbstractCredentialStoreOnlineTest { + + private static final String TEST_CREDENTIAL_STORE_NAME = "CreaperTestCredentialStore"; + private static final Address TEST_CREDENTIAL_STORE_ADDRESS = SUBSYSTEM_ADDRESS + .and("credential-store", TEST_CREDENTIAL_STORE_NAME); + + private static final String TEST_CREDENTIAL_STORE_ALIAS_NAME = "creapertestcredentialstorealias"; + private static final String TEST_CREDENTIAL_STORE_ALIAS_NAME2 = "creapertestcredentialstorealias2"; + + private static final String PATH = "path"; + private static final String TMP = "tmp"; + private static final Address TEST_PATH_TMP_ADDRESS = Address.root() + .and(PATH, TMP); + + @ClassRule + public static TemporaryFolder tmp = new TemporaryFolder(); + + @BeforeClass + public static void createTmpPath() throws Exception { + OnlineManagementClient client = null; + try { + client = createManagementClient(); + AddTmpDirectoryToPath addTargetToPath = new AddTmpDirectoryToPath(); + client.apply(addTargetToPath); + } finally { + if (client != null) { + client.close(); + } + } + } + + @Before + public void createCredentialStore() throws Exception { + AddCredentialStore addCredentialStore = new AddCredentialStore.Builder(TEST_CREDENTIAL_STORE_NAME) + .create(true) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("somePassword") + .build()) + .relativeTo("tmp") + .build(); + + client.apply(addCredentialStore); + } + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_CREDENTIAL_STORE_ADDRESS); + administration.reloadIfRequired(); + } + + @AfterClass + public static void removeTmpPath() throws Exception { + OnlineManagementClient client = null; + try { + client = createManagementClient(); + Operations operations = new Operations(client); + operations.removeIfExists(TEST_PATH_TMP_ADDRESS); + } finally { + if (client != null) { + client.close(); + } + } + } + + @Test + public void addSimpleCredentialStoreAlias() throws Exception { + AddCredentialStoreAlias addCredentialStoreAlias + = new AddCredentialStoreAlias.Builder(TEST_CREDENTIAL_STORE_ALIAS_NAME) + .credentialStore(TEST_CREDENTIAL_STORE_NAME) + .secretValue("someSecretValue") + .replaceExisting() + .build(); + + client.apply(addCredentialStoreAlias); + + assertTrue("Credential store alias should be created", + aliasExists(TEST_CREDENTIAL_STORE_ADDRESS, TEST_CREDENTIAL_STORE_ALIAS_NAME)); + } + + @Test + public void addFullCredentialStoreAlias() throws Exception { + AddCredentialStoreAlias addCredentialStoreAlias + = new AddCredentialStoreAlias.Builder(TEST_CREDENTIAL_STORE_ALIAS_NAME) + .credentialStore(TEST_CREDENTIAL_STORE_NAME) + .secretValue("someSecretValue") + .entryType(AddCredentialStoreAlias.EntryType.PASSWORD_CREDENTIAL) + .replaceExisting() + .build(); + + client.apply(addCredentialStoreAlias); + assertTrue("Credential store alias should be created", + aliasExists(TEST_CREDENTIAL_STORE_ADDRESS, TEST_CREDENTIAL_STORE_ALIAS_NAME)); + } + + @Test + public void addTwoCredentialStoreAliases() throws Exception { + AddCredentialStoreAlias addCredentialStoreAlias + = new AddCredentialStoreAlias.Builder(TEST_CREDENTIAL_STORE_ALIAS_NAME) + .credentialStore(TEST_CREDENTIAL_STORE_NAME) + .secretValue("someSecretValue") + .replaceExisting() + .build(); + + AddCredentialStoreAlias addCredentialStoreAlias2 + = new AddCredentialStoreAlias.Builder(TEST_CREDENTIAL_STORE_ALIAS_NAME2) + .credentialStore(TEST_CREDENTIAL_STORE_NAME) + .secretValue("someOtherValue") + .replaceExisting() + .build(); + + client.apply(addCredentialStoreAlias); + client.apply(addCredentialStoreAlias2); + + assertTrue("Credential store alias should be created", + aliasExists(TEST_CREDENTIAL_STORE_ADDRESS, TEST_CREDENTIAL_STORE_ALIAS_NAME)); + assertTrue("Credential store alias should be created", + aliasExists(TEST_CREDENTIAL_STORE_ADDRESS, TEST_CREDENTIAL_STORE_ALIAS_NAME2)); + } + + @Test(expected = CommandFailedException.class) + public void addExistCredentialStoreAliasNotAllowed() throws Exception { + AddCredentialStoreAlias addCredentialStoreAlias + = new AddCredentialStoreAlias.Builder(TEST_CREDENTIAL_STORE_ALIAS_NAME) + .credentialStore(TEST_CREDENTIAL_STORE_NAME) + .secretValue("someSecretValue") + .build(); + + AddCredentialStoreAlias addCredentialStoreAlias2 + = new AddCredentialStoreAlias.Builder(TEST_CREDENTIAL_STORE_ALIAS_NAME) + .credentialStore(TEST_CREDENTIAL_STORE_NAME) + .secretValue("someOtherValue") + .build(); + + client.apply(addCredentialStoreAlias); + assertTrue("Credential store alias should be created", ops.exists(TEST_CREDENTIAL_STORE_ADDRESS)); + client.apply(addCredentialStoreAlias2); + fail("Credential store alias creapertestcredentialstorealias already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistCredentialStoreAliasAllowed() throws Exception { + AddCredentialStoreAlias addCredentialStoreAlias + = new AddCredentialStoreAlias.Builder(TEST_CREDENTIAL_STORE_ALIAS_NAME) + .credentialStore(TEST_CREDENTIAL_STORE_NAME) + .secretValue("someSecretValue") + .build(); + + AddCredentialStoreAlias addCredentialStoreAlias2 + = new AddCredentialStoreAlias.Builder(TEST_CREDENTIAL_STORE_ALIAS_NAME) + .credentialStore(TEST_CREDENTIAL_STORE_NAME) + .secretValue("someOtherValue") + .replaceExisting() + .build(); + + client.apply(addCredentialStoreAlias); + assertTrue("Credential store alias should be created", ops.exists(TEST_CREDENTIAL_STORE_ADDRESS)); + client.apply(addCredentialStoreAlias2); + assertTrue("Credential store alias should be created", ops.exists(TEST_CREDENTIAL_STORE_ADDRESS)); + } + + @Test(expected = IllegalArgumentException.class) + public void addCredentialStoreAlias_nullName() throws Exception { + new AddCredentialStoreAlias.Builder(null) + .credentialStore(TEST_CREDENTIAL_STORE_NAME) + .secretValue("someSecretValue") + .build(); + + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCredentialStoreAlias_emptyName() throws Exception { + new AddCredentialStoreAlias.Builder("") + .credentialStore(TEST_CREDENTIAL_STORE_NAME) + .secretValue("someSecretValue") + .build(); + + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCredentialStoreAlias_nullCredentialStore() throws Exception { + new AddCredentialStoreAlias.Builder(TEST_CREDENTIAL_STORE_ALIAS_NAME) + .credentialStore(null) + .secretValue("someSecretValue") + .build(); + + fail("Creating command with null credential-store should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCredentialStoreAlias_emptyCredentialStore() throws Exception { + new AddCredentialStoreAlias.Builder(TEST_CREDENTIAL_STORE_ALIAS_NAME) + .credentialStore("") + .secretValue("someSecretValue") + .build(); + + fail("Creating command with empty credential-store should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCredentialStoreAlias_nullSecretValue() throws Exception { + new AddCredentialStoreAlias.Builder(TEST_CREDENTIAL_STORE_ALIAS_NAME) + .credentialStore(TEST_CREDENTIAL_STORE_NAME) + .secretValue(null) + .build(); + + fail("Creating command with null secret-value should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCredentialStoreAlias_emptySecretValue() throws Exception { + new AddCredentialStoreAlias.Builder(TEST_CREDENTIAL_STORE_ALIAS_NAME) + .credentialStore(TEST_CREDENTIAL_STORE_NAME) + .secretValue("") + .build(); + + fail("Creating command with empty secret-value should throw exception"); + } + + private static final class AddTmpDirectoryToPath implements OnlineCommand { + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + Operations ops = new Operations(ctx.client); + Address pathAddress = Address.root() + .and(PATH, TMP); + + ops.add(pathAddress, Values.empty() + .and(PATH, tmp.getRoot().getAbsolutePath())); + } + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/AddCredentialStoreOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/AddCredentialStoreOnlineTest.java new file mode 100644 index 00000000..12d2d391 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/AddCredentialStoreOnlineTest.java @@ -0,0 +1,243 @@ +package org.wildfly.extras.creaper.commands.elytron.credentialstore; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.IOException; +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.commands.elytron.CredentialRef; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddCredentialStoreOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_CREDENTIAL_STORE_NAME = "CreaperTestCredentialStore"; + private static final Address TEST_CREDENTIAL_STORE_ADDRESS = SUBSYSTEM_ADDRESS + .and("credential-store", TEST_CREDENTIAL_STORE_NAME); + private static final String TEST_CREDENTIAL_STORE_NAME2 = "CreaperTestCredentialStore2"; + private static final Address TEST_CREDENTIAL_STORE_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("credential-store", TEST_CREDENTIAL_STORE_NAME2); + + private static final String TEST_PASSWORD = "somePassword"; + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_CREDENTIAL_STORE_ADDRESS2); + ops.removeIfExists(TEST_CREDENTIAL_STORE_ADDRESS); + administration.reloadIfRequired(); + } + + @AfterClass + public static void removeCreatedCredentialStoreFiles() throws IOException { + deleteIfExists(TEST_CREDENTIAL_STORE_NAME); + deleteIfExists(TEST_CREDENTIAL_STORE_NAME2); + } + + @Test + public void addSimpleCredentialStore() throws Exception { + AddCredentialStore addCredentialStore = new AddCredentialStore.Builder(TEST_CREDENTIAL_STORE_NAME) + .create(true) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_PASSWORD) + .build()) + .build(); + + client.apply(addCredentialStore); + + assertTrue("Credential store should be created", ops.exists(TEST_CREDENTIAL_STORE_ADDRESS)); + } + + @Test + public void addFullCredentialStoreClearText() throws Exception { + AddCredentialStore addCredentialStore = new AddCredentialStore.Builder(TEST_CREDENTIAL_STORE_NAME) + .create(true) + .providers("elytron") + .providerName("WildFlyElytron") + .otherProviders("elytron") + .relativeTo("jboss.server.data.dir") + .type("KeyStoreCredentialStore") + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_PASSWORD) + .build()) + .addImplementationProperties("cryptoAlg", "MD5") + .location("/path/to/nowhere") + .modifiable(true) + .build(); + + client.apply(addCredentialStore); + assertTrue("Credential store should be created", ops.exists(TEST_CREDENTIAL_STORE_ADDRESS)); + + checkAttribute(TEST_CREDENTIAL_STORE_ADDRESS, "relative-to", "jboss.server.data.dir"); + checkAttribute(TEST_CREDENTIAL_STORE_ADDRESS, "type", "KeyStoreCredentialStore"); + checkAttribute(TEST_CREDENTIAL_STORE_ADDRESS, "credential-reference.clear-text", TEST_PASSWORD); + checkAttribute(TEST_CREDENTIAL_STORE_ADDRESS, "providers", "elytron"); + checkAttribute(TEST_CREDENTIAL_STORE_ADDRESS, "provider-name", "WildFlyElytron"); + checkAttribute(TEST_CREDENTIAL_STORE_ADDRESS, "other-providers", "elytron"); + checkAttribute(TEST_CREDENTIAL_STORE_ADDRESS, "implementation-properties.cryptoAlg", "MD5"); + checkAttribute(TEST_CREDENTIAL_STORE_ADDRESS, "location", "/path/to/nowhere"); + checkAttribute(TEST_CREDENTIAL_STORE_ADDRESS, "modifiable", "true"); + } + + @Test + public void addFullCredentialStoreAliasStore() throws Exception { + AddCredentialStore addCredentialStore = new AddCredentialStore.Builder(TEST_CREDENTIAL_STORE_NAME) + .create(true) + .relativeTo("jboss.server.data.dir") + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_PASSWORD) + .build()) + .build(); + + AddCredentialStoreAlias addCredentialStoreAlias = new AddCredentialStoreAlias.Builder("alias") + .credentialStore(TEST_CREDENTIAL_STORE_NAME) + .secretValue("secret") + .build(); + client.apply(addCredentialStore, addCredentialStoreAlias); + assertTrue("Credential store should be created", ops.exists(TEST_CREDENTIAL_STORE_ADDRESS)); + + addCredentialStore = new AddCredentialStore.Builder(TEST_CREDENTIAL_STORE_NAME2) + .create(true) + .relativeTo("jboss.server.data.dir") + .type("KeyStoreCredentialStore") + .credentialReference(new CredentialRef.CredentialRefBuilder() + .alias("alias") + .store(TEST_CREDENTIAL_STORE_NAME) + .build()) + .build(); + + client.apply(addCredentialStore); + assertTrue("Credential store should be created", ops.exists(TEST_CREDENTIAL_STORE_ADDRESS2)); + + checkAttribute(TEST_CREDENTIAL_STORE_ADDRESS2, "relative-to", "jboss.server.data.dir"); + checkAttribute(TEST_CREDENTIAL_STORE_ADDRESS2, "type", "KeyStoreCredentialStore"); + checkAttribute(TEST_CREDENTIAL_STORE_ADDRESS2, "credential-reference.alias", "alias"); + checkAttribute(TEST_CREDENTIAL_STORE_ADDRESS2, "credential-reference.store", TEST_CREDENTIAL_STORE_NAME); + } + + @Test + public void addTwoCredentialStores() throws Exception { + AddCredentialStore addCredentialStore = new AddCredentialStore.Builder(TEST_CREDENTIAL_STORE_NAME) + .create(true) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_PASSWORD) + .build()) + .build(); + + AddCredentialStore addCredentialStore2 = new AddCredentialStore.Builder(TEST_CREDENTIAL_STORE_NAME2) + .create(true) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_PASSWORD) + .build()) + .build(); + + client.apply(addCredentialStore); + client.apply(addCredentialStore2); + + assertTrue("Credential store should be created", ops.exists(TEST_CREDENTIAL_STORE_ADDRESS)); + assertTrue("Second credential store should be created", ops.exists(TEST_CREDENTIAL_STORE_ADDRESS2)); + } + + @Test(expected = CommandFailedException.class) + public void addExistCredentialStoreNotAllowed() throws Exception { + AddCredentialStore addCredentialStore = new AddCredentialStore.Builder(TEST_CREDENTIAL_STORE_NAME) + .create(true) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_PASSWORD) + .build()) + .build(); + + AddCredentialStore addCredentialStore2 = new AddCredentialStore.Builder(TEST_CREDENTIAL_STORE_NAME) + .create(true) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_PASSWORD) + .build()) + .build(); + + client.apply(addCredentialStore); + assertTrue("Credential store should be created", ops.exists(TEST_CREDENTIAL_STORE_ADDRESS)); + client.apply(addCredentialStore2); + fail("Credential store CreaperTestCredentialStore already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistCredentialStoreAllowed() throws Exception { + AddCredentialStore addCredentialStore = new AddCredentialStore.Builder(TEST_CREDENTIAL_STORE_NAME) + .create(true) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_PASSWORD) + .build()) + .modifiable(false) + .build(); + + AddCredentialStore addCredentialStore2 = new AddCredentialStore.Builder(TEST_CREDENTIAL_STORE_NAME) + .create(true) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_PASSWORD) + .build()) + .modifiable(true) + .replaceExisting() + .build(); + + client.apply(addCredentialStore); + assertTrue("Constant permission mapper should be created", ops.exists(TEST_CREDENTIAL_STORE_ADDRESS)); + client.apply(addCredentialStore2); + assertTrue("Constant permission mapper should be created", ops.exists(TEST_CREDENTIAL_STORE_ADDRESS)); + + // check whether it was really rewritten + checkAttribute(TEST_CREDENTIAL_STORE_ADDRESS, "modifiable", "true"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCredentialStore_nullName() throws Exception { + new AddCredentialStore.Builder(null) + .create(true) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_PASSWORD) + .build()) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCredentialStore_emptyName() throws Exception { + new AddCredentialStore.Builder("") + .create(true) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_PASSWORD) + .build()) + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCredentialStore_nullCredentialReference() throws Exception { + new AddCredentialStore.Builder(TEST_CREDENTIAL_STORE_NAME) + .create(true) + .credentialReference(null) + .build(); + } + + @Test(expected = IllegalArgumentException.class) + public void addCredentialStore_insufficientCredentialReference() throws Exception { + new AddCredentialStore.Builder(TEST_CREDENTIAL_STORE_NAME) + .create(true) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .alias("someAlias") + .build()) + .build(); + } + + private static void deleteIfExists(String filename) { + File file = new File(filename); + if (file.exists()) { + file.delete(); + } + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/RemoveCredentialStoreAliasOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/RemoveCredentialStoreAliasOnlineTest.java new file mode 100644 index 00000000..78788ef4 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/RemoveCredentialStoreAliasOnlineTest.java @@ -0,0 +1,152 @@ +package org.wildfly.extras.creaper.commands.elytron.credentialstore; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.CredentialRef; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.OnlineCommand; +import org.wildfly.extras.creaper.core.online.OnlineCommandContext; +import org.wildfly.extras.creaper.core.online.OnlineManagementClient; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.Values; + +@RunWith(Arquillian.class) +public class RemoveCredentialStoreAliasOnlineTest extends AbstractCredentialStoreOnlineTest { + + private static final String TEST_CREDENTIAL_STORE_NAME = "CreaperTestCredentialStore"; + private static final Address TEST_CREDENTIAL_STORE_ADDRESS = SUBSYSTEM_ADDRESS.and("credential-store", + TEST_CREDENTIAL_STORE_NAME); + private static final String TEST_CREDENTIAL_STORE_ALIAS_NAME = "creapertestcredentialstorealias"; + + private static final String PATH = "path"; + private static final String TMP = "tmp"; + private static final Address TEST_PATH_TMP_ADDRESS = Address.root() + .and(PATH, TMP); + + @ClassRule + public static TemporaryFolder tmpFolder = new TemporaryFolder(); + + @BeforeClass + public static void createTmpPath() throws Exception { + OnlineManagementClient client = null; + try { + client = createManagementClient(); + AddTmpDirectoryToPath addTargetToPath = new AddTmpDirectoryToPath(); + client.apply(addTargetToPath); + } finally { + if (client != null) { + client.close(); + } + } + } + + @Before + public void createCredentialStore() throws Exception { + AddCredentialStore addCredentialStore = new AddCredentialStore.Builder(TEST_CREDENTIAL_STORE_NAME) + .create(true) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("somePassword") + .build()) + .relativeTo("tmp") + .build(); + + client.apply(addCredentialStore); + } + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_CREDENTIAL_STORE_ADDRESS); + administration.reloadIfRequired(); + } + + @AfterClass + public static void removeTmpPath() throws Exception { + OnlineManagementClient client = null; + try { + client = createManagementClient(); + Operations operations = new Operations(client); + operations.removeIfExists(TEST_PATH_TMP_ADDRESS); + } finally { + if (client != null) { + client.close(); + } + } + } + + @Test + public void removeCredentialStore() throws Exception { + AddCredentialStoreAlias addCredentialStoreAlias + = new AddCredentialStoreAlias.Builder(TEST_CREDENTIAL_STORE_ALIAS_NAME) + .credentialStore(TEST_CREDENTIAL_STORE_NAME) + .secretValue("someSecretValue") + .build(); + client.apply(addCredentialStoreAlias); + assertTrue("Credential store alias should be created", + aliasExists(TEST_CREDENTIAL_STORE_ADDRESS, TEST_CREDENTIAL_STORE_ALIAS_NAME)); + + RemoveCredentialStoreAlias removeCredentialStoreAlias + = new RemoveCredentialStoreAlias(TEST_CREDENTIAL_STORE_NAME, TEST_CREDENTIAL_STORE_ALIAS_NAME); + + client.apply(removeCredentialStoreAlias); + assertFalse("Credential store alias should be removed", + aliasExists(TEST_CREDENTIAL_STORE_ADDRESS, TEST_CREDENTIAL_STORE_ALIAS_NAME)); + } + + @Test(expected = CommandFailedException.class) + public void removeNonExistingCredentialStore() throws Exception { + RemoveCredentialStoreAlias removeCredentialStoreAlias + = new RemoveCredentialStoreAlias(TEST_CREDENTIAL_STORE_NAME, TEST_CREDENTIAL_STORE_ALIAS_NAME); + client.apply(removeCredentialStoreAlias); + + fail("Specified credential store alias does not exist in configuration, an exception should be thrown"); + } + + @Test(expected = IllegalArgumentException.class) + public void removeCredentialStore_nullCredentialStore() throws Exception { + new RemoveCredentialStoreAlias(null, TEST_CREDENTIAL_STORE_ALIAS_NAME); + fail("Creating command with null credential store name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void removeCredentialStore_emptyCredentialStore() throws Exception { + new RemoveCredentialStoreAlias("", TEST_CREDENTIAL_STORE_ALIAS_NAME); + fail("Creating command with empty credential store name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void removeCredentialStore_nullCredentialStoreAlias() throws Exception { + new RemoveCredentialStoreAlias(TEST_CREDENTIAL_STORE_NAME, null); + fail("Creating command with null credential store alias name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void removeCredentialStore_emptyCredentialStoreAlias() throws Exception { + new RemoveCredentialStoreAlias(TEST_CREDENTIAL_STORE_NAME, ""); + fail("Creating command with empty credential store alias name should throw exception"); + } + + private static final class AddTmpDirectoryToPath implements OnlineCommand { + + @Override + public void apply(OnlineCommandContext ctx) throws Exception { + Operations ops = new Operations(ctx.client); + Address pathAddress = Address.root() + .and(PATH, TMP); + + ops.add(pathAddress, Values.empty() + .and(PATH, tmpFolder.getRoot().getAbsolutePath())); + } + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/RemoveCredentialStoreOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/RemoveCredentialStoreOnlineTest.java new file mode 100644 index 00000000..33ef109a --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credentialstore/RemoveCredentialStoreOnlineTest.java @@ -0,0 +1,66 @@ +package org.wildfly.extras.creaper.commands.elytron.credentialstore; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.commands.elytron.CredentialRef; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class RemoveCredentialStoreOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_CREDENTIAL_STORE_NAME = "CreaperTestCredentialStore"; + private static final Address TEST_CREDENTIAL_STORE_ADDRESS = SUBSYSTEM_ADDRESS + .and("credential-store", TEST_CREDENTIAL_STORE_NAME); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_CREDENTIAL_STORE_ADDRESS); + administration.reloadIfRequired(); + } + + @Test + public void removeCredentialStore() throws Exception { + AddCredentialStore addCredentialStore = new AddCredentialStore.Builder(TEST_CREDENTIAL_STORE_NAME) + .create(true) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("somePassword") + .build()) + .build(); + + client.apply(addCredentialStore); + assertTrue("Credential store should be created", ops.exists(TEST_CREDENTIAL_STORE_ADDRESS)); + + RemoveCredentialStore removeCredentialStore = new RemoveCredentialStore(TEST_CREDENTIAL_STORE_NAME); + + client.apply(removeCredentialStore); + assertFalse("Credential store should be removed", ops.exists(TEST_CREDENTIAL_STORE_ADDRESS)); + } + + @Test(expected = CommandFailedException.class) + public void removeNonExistingCredentialStore() throws Exception { + RemoveCredentialStore removeCredentialStore = new RemoveCredentialStore(TEST_CREDENTIAL_STORE_NAME); + client.apply(removeCredentialStore); + + fail("Specified credential store does not exist in configuration, an exception should be thrown"); + } + + @Test(expected = IllegalArgumentException.class) + public void removeCredentialStore_nullName() throws Exception { + new RemoveCredentialStore(null); + fail("Creating command with null credential store name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void removeCredentialStore_emptyName() throws Exception { + new RemoveCredentialStore(""); + fail("Creating command with empty credential store name should throw exception"); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credfactory/AddCustomCredentialSecurityFactoryOfflineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credfactory/AddCustomCredentialSecurityFactoryOfflineTest.java new file mode 100644 index 00000000..0cbdacf7 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credfactory/AddCustomCredentialSecurityFactoryOfflineTest.java @@ -0,0 +1,34 @@ +package org.wildfly.extras.creaper.commands.elytron.credfactory; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractAddCustomOfflineTest; + + +@RunWith(Arquillian.class) +public class AddCustomCredentialSecurityFactoryOfflineTest extends AbstractAddCustomOfflineTest { + + public String convertSubsystem(String subsystemString) { + return subsystemString.replaceAll(PARENT_TYPE, "credential-security-factories") + .replaceAll(CUSTOM_TYPE, "custom-credential-security-factory") + .replaceAll(CUSTOM_NAME, getAddCustomName()) + .replaceAll(CLASS_NAME, getClassName()) + .replaceAll(MODULE_NAME, getModuleName()); + } + + public String getAddCustomName() { + return "customCredSecFac"; + } + + public Object getBuilderObject(String name) { + return new AddCustomCredentialSecurityFactory.Builder(name); + } + + public String getModuleName() { + return "org.jboss.customcredsecfacimpl"; + } + + public String getClassName() { + return "SomeCustomCredentialSecurityFactory"; + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credfactory/AddCustomCredentialSecurityFactoryOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credfactory/AddCustomCredentialSecurityFactoryOnlineTest.java new file mode 100644 index 00000000..fbafd29b --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credfactory/AddCustomCredentialSecurityFactoryOnlineTest.java @@ -0,0 +1,66 @@ +package org.wildfly.extras.creaper.commands.elytron.credfactory; + +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; + + +@RunWith(Arquillian.class) +public class AddCustomCredentialSecurityFactoryOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_ADD_CUSTOM_CRED_SEC_FACTORY_NAME = "CreaperTestAddCustomCredentialSecurityFactory"; + + @Test(expected = IllegalArgumentException.class) + public void addCustomCredentialSecurityFactory_nullName() throws Exception { + new AddCustomCredentialSecurityFactory.Builder(null) + .className("someClassName") + .module("someModule"); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAddCustomCredentialSecurityFactory_emptyName() throws Exception { + new AddCustomCredentialSecurityFactory.Builder("") + .className("someClassName") + .module("someModule"); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomCredentialSecurityFactory_noClassName() throws Exception { + new AddCustomCredentialSecurityFactory.Builder(TEST_ADD_CUSTOM_CRED_SEC_FACTORY_NAME) + .module("someModule") + .build(); + fail("Creating command with no classname should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomCredentialSecurityFactory_emptyClassName() throws Exception { + new AddCustomCredentialSecurityFactory.Builder(TEST_ADD_CUSTOM_CRED_SEC_FACTORY_NAME) + .className("") + .module("someModule") + .build(); + fail("Creating command with empty classname should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomCredentialSecurityFactory_noModule() throws Exception { + new AddCustomCredentialSecurityFactory.Builder(TEST_ADD_CUSTOM_CRED_SEC_FACTORY_NAME) + .className("someClassName") + .build(); + fail("Creating command with no module should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomCredentialSecurityFactory_emptyModule() throws Exception { + new AddCustomCredentialSecurityFactory.Builder(TEST_ADD_CUSTOM_CRED_SEC_FACTORY_NAME) + .className("someClassName") + .module("") + .build(); + fail("Creating command with empty module should throw exception"); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credfactory/AddKerberosSecurityFactoryOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credfactory/AddKerberosSecurityFactoryOnlineTest.java new file mode 100644 index 00000000..b3c97221 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/credfactory/AddKerberosSecurityFactoryOnlineTest.java @@ -0,0 +1,197 @@ +package org.wildfly.extras.creaper.commands.elytron.credfactory; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.Arrays; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddKerberosSecurityFactoryOnlineTest extends AbstractElytronOnlineTest { + + private static final String KRB_NAME = "CreaperTestKerberosSecurityFactory"; + private static final String KRB_NAME2 = "CreaperTestKerberosSecurityFactory2"; + private static final String KRB_PRINCIPAL = "principal1"; + private static final String KRB_PRINCIPAL2 = "principal2"; + private static final String KRB_PATH = "/path/to/keytab"; + private static final String KRB_OIDS = "1.2.840.113554.1.2.2"; + private static final Address KRB_ADDRESS = SUBSYSTEM_ADDRESS.and("kerberos-security-factory", KRB_NAME); + private static final Address KRB_ADDRESS2 = SUBSYSTEM_ADDRESS.and("kerberos-security-factory", KRB_NAME2); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(KRB_ADDRESS); + ops.removeIfExists(KRB_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleKerberosSecurityFactory() throws Exception { + AddKerberosSecurityFactory addKerberosSecurityFactory = new AddKerberosSecurityFactory.Builder(KRB_NAME) + .principal(KRB_PRINCIPAL) + .path(KRB_PATH) + .build(); + assertFalse("The kerberos security factory should not exist", ops.exists(KRB_ADDRESS)); + client.apply(addKerberosSecurityFactory); + assertTrue("Kerberos security factory should be created", ops.exists(KRB_ADDRESS)); + } + + @Test + public void addTwoSimpleKerberosSecurityFactory() throws Exception { + AddKerberosSecurityFactory addKerberosSecurityFactory = new AddKerberosSecurityFactory.Builder(KRB_NAME) + .principal(KRB_PRINCIPAL) + .path(KRB_PATH) + .build(); + AddKerberosSecurityFactory addKerberosSecurityFactory2 = new AddKerberosSecurityFactory.Builder(KRB_NAME2) + .principal(KRB_PRINCIPAL) + .path(KRB_PATH) + .build(); + + assertFalse("The kerberos security factory should not exist", ops.exists(KRB_ADDRESS)); + assertFalse("The kerberos security factory should not exist", ops.exists(KRB_ADDRESS2)); + + client.apply(addKerberosSecurityFactory); + client.apply(addKerberosSecurityFactory2); + + assertTrue("Kerberos security factory should be created", ops.exists(KRB_ADDRESS)); + assertTrue("Kerberos security factory should be created", ops.exists(KRB_ADDRESS2)); + } + + @Test(expected = CommandFailedException.class) + public void addDuplicateKerberosSecurityFactoryNotAllowed() throws Exception { + AddKerberosSecurityFactory addKerberosSecurityFactory = new AddKerberosSecurityFactory.Builder(KRB_NAME) + .principal(KRB_PRINCIPAL) + .path(KRB_PATH) + .build(); + AddKerberosSecurityFactory addKerberosSecurityFactory2 = new AddKerberosSecurityFactory.Builder(KRB_NAME) + .principal(KRB_PRINCIPAL) + .path(KRB_PATH) + .build(); + + client.apply(addKerberosSecurityFactory); + assertTrue("The kerberos security factory should be created", ops.exists(KRB_ADDRESS)); + + client.apply(addKerberosSecurityFactory2); + fail("The kerberos security factory is already configured, exception should be thrown"); + } + + @Test + public void addDuplicateKerberosSecurityFactoryAllowed() throws Exception { + AddKerberosSecurityFactory addKerberosSecurityFactory = new AddKerberosSecurityFactory.Builder(KRB_NAME) + .principal(KRB_PRINCIPAL) + .path(KRB_PATH) + .build(); + AddKerberosSecurityFactory addKerberosSecurityFactory2 = new AddKerberosSecurityFactory.Builder(KRB_NAME) + .principal(KRB_PRINCIPAL2) + .path(KRB_PATH) + .replaceExisting() + .build(); + + client.apply(addKerberosSecurityFactory); + assertTrue("The kerberos security factory should be created", ops.exists(KRB_ADDRESS)); + + client.apply(addKerberosSecurityFactory2); + assertTrue("The kerberos security factory should be created", ops.exists(KRB_ADDRESS)); + // check whether it was really rewritten + checkAttribute(KRB_ADDRESS, "principal", KRB_PRINCIPAL2); + } + + @Test + public void addFullKerberosSecurityFactory() throws Exception { + AddKerberosSecurityFactory addKerberosSecurityFactory = new AddKerberosSecurityFactory.Builder(KRB_NAME) + .principal(KRB_PRINCIPAL) + .path(KRB_PATH) + .mechanismOIDs(KRB_OIDS, "1.2.840.48018.1.2.2", "1.3.6.1.5.5.2") + .mechanismNames("KRB5", "SPNEGO") + .minimumRemainingLifetime(1) + .relativeTo("jboss.server.config.dir") + .requestLifetime(2) + .debug(true) + .server(false) + .obtainKerberosTicket(true) + .wrapGssCredential(true) + .required(false) + .addOption("a", "b") + .addOption("debug", "false") + .build(); + client.apply(addKerberosSecurityFactory); + assertTrue("Kerberos security factory should be created", ops.exists(KRB_ADDRESS)); + + checkAttribute(KRB_ADDRESS, "principal", KRB_PRINCIPAL); + checkAttribute(KRB_ADDRESS, "path", KRB_PATH); + checkAttribute(KRB_ADDRESS, "mechanism-oids", Arrays.asList(KRB_OIDS, "1.2.840.48018.1.2.2", "1.3.6.1.5.5.2")); + checkAttribute(KRB_ADDRESS, "mechanism-names", Arrays.asList("KRB5", "SPNEGO")); + checkAttribute(KRB_ADDRESS, "minimum-remaining-lifetime", "1"); + checkAttribute(KRB_ADDRESS, "relative-to", "jboss.server.config.dir"); + checkAttribute(KRB_ADDRESS, "request-lifetime", "2"); + checkAttribute(KRB_ADDRESS, "debug", "true"); + checkAttribute(KRB_ADDRESS, "server", "false"); + checkAttribute(KRB_ADDRESS, "obtain-kerberos-ticket", "true"); + checkAttribute(KRB_ADDRESS, "wrap-gss-credential", "true"); + checkAttribute(KRB_ADDRESS, "required", "false"); + checkAttributeObject(KRB_ADDRESS, "options", "debug", "false"); + } + + @Test(expected = IllegalArgumentException.class) + public void addKerberosSecurityFactory_nullName() throws Exception { + AddKerberosSecurityFactory addKerberosSecurityFactory = new AddKerberosSecurityFactory.Builder(null) + .principal(KRB_PRINCIPAL) + .path(KRB_PATH) + .build(); + fail("Creating command with null kerberos security factory name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addKerberosSecurityFactory_emptyName() throws Exception { + AddKerberosSecurityFactory addKerberosSecurityFactory = new AddKerberosSecurityFactory.Builder("") + .principal(KRB_PRINCIPAL) + .path(KRB_PATH) + .build(); + fail("Creating command with empty kerberos security factory name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addKerberosSecurityFactory_nullPath() throws Exception { + AddKerberosSecurityFactory addKerberosSecurityFactory = new AddKerberosSecurityFactory.Builder(KRB_NAME) + .principal(KRB_PRINCIPAL) + .path(null) + .build(); + fail("Creating command with null kerberos security factory path should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addKerberosSecurityFactory_emptyPath() throws Exception { + AddKerberosSecurityFactory addKerberosSecurityFactory = new AddKerberosSecurityFactory.Builder(KRB_NAME) + .principal(KRB_PRINCIPAL) + .path("") + .build(); + fail("Creating command with empty kerberos security factory path should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addKerberosSecurityFactory_nullPrincipal() throws Exception { + AddKerberosSecurityFactory addKerberosSecurityFactory = new AddKerberosSecurityFactory.Builder(KRB_NAME) + .principal(null) + .path(KRB_PATH) + .build(); + fail("Creating command with null kerberos security factory principal should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addKerberosSecurityFactory_emptyPrincipal() throws Exception { + AddKerberosSecurityFactory addKerberosSecurityFactory = new AddKerberosSecurityFactory.Builder(KRB_NAME) + .principal("") + .path(KRB_PATH) + .build(); + fail("Creating command with empty kerberos security factory principal should throw exception"); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/dircontext/AddDirContextOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/dircontext/AddDirContextOnlineTest.java new file mode 100644 index 00000000..22e54faf --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/dircontext/AddDirContextOnlineTest.java @@ -0,0 +1,260 @@ +package org.wildfly.extras.creaper.commands.elytron.dircontext; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.commands.elytron.CredentialRef; +import org.wildfly.extras.creaper.commands.elytron.Property; +import org.wildfly.extras.creaper.commands.elytron.authenticationclient.AddAuthenticationContext; +import org.wildfly.extras.creaper.commands.elytron.tls.AddKeyManager; +import org.wildfly.extras.creaper.commands.elytron.tls.AddKeyStore; +import org.wildfly.extras.creaper.commands.elytron.tls.AddServerSSLContext; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddDirContextOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_DIR_CONTEXT_NAME = "CreaperTestDirContext"; + private static final Address TEST_DIR_CONTEXT_ADDRESS = SUBSYSTEM_ADDRESS + .and("dir-context", TEST_DIR_CONTEXT_NAME); + private static final String TEST_DIR_CONTEXT_NAME2 = "CreaperTestDirContext2"; + private static final Address TEST_DIR_CONTEXT_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("dir-context", TEST_DIR_CONTEXT_NAME2); + + private static final String TEST_SERVER_SSL_CONTEXT = "CreaperTestSslContext"; + private static final Address TEST_SERVER_SSL_CONTEXT_ADDRESS = SUBSYSTEM_ADDRESS + .and("server-ssl-context", TEST_SERVER_SSL_CONTEXT); + + private static final String TEST_AUTHENTICATION_CONTEXT_NAME = "CreaperTestAuthenticationContext"; + private static final Address TEST_AUTHENTICATION_CONTEXT_ADDRESS = SUBSYSTEM_ADDRESS + .and("authentication-context", TEST_AUTHENTICATION_CONTEXT_NAME); + + private static final String TEST_KEY_STORE_NAME = "CreaperTestKeyStore"; + private static final Address TEST_KEY_STORE_NAME_ADDRESS = SUBSYSTEM_ADDRESS + .and("key-store", TEST_KEY_STORE_NAME); + private static final String TEST_KEY_STORE_TYPE = "JKS"; + private static final String TEST_KEY_STORE_PASSWORD = "password"; + private static final String TEST_KEY_PASSWORD = "password"; + private static final String TEST_KEY_MNGR_NAME = "CreaperTestKeyManager"; + private static final Address TEST_KEY_MNGR_NAME_ADDRESS = SUBSYSTEM_ADDRESS + .and("key-manager", TEST_KEY_MNGR_NAME); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_DIR_CONTEXT_ADDRESS); + ops.removeIfExists(TEST_DIR_CONTEXT_ADDRESS2); + ops.removeIfExists(TEST_SERVER_SSL_CONTEXT_ADDRESS); + ops.removeIfExists(TEST_KEY_MNGR_NAME_ADDRESS); + ops.removeIfExists(TEST_KEY_STORE_NAME_ADDRESS); + ops.removeIfExists(TEST_AUTHENTICATION_CONTEXT_ADDRESS); + administration.reloadIfRequired(); + } + + @Test + public void addDirContext() throws Exception { + AddDirContext addDirContext = new AddDirContext.Builder(TEST_DIR_CONTEXT_NAME) + .url("localhost") + .build(); + client.apply(addDirContext); + + assertTrue("Dir context should be created", ops.exists(TEST_DIR_CONTEXT_ADDRESS)); + } + + @Test + public void addDirContexts() throws Exception { + AddDirContext addDirContext = new AddDirContext.Builder(TEST_DIR_CONTEXT_NAME) + .url("localhost") + .build(); + + AddDirContext addDirContext2 = new AddDirContext.Builder(TEST_DIR_CONTEXT_NAME2) + .url("localhost") + .build(); + + client.apply(addDirContext); + client.apply(addDirContext2); + + assertTrue("Dir context should be created", ops.exists(TEST_DIR_CONTEXT_ADDRESS)); + assertTrue("Second dir context should be created", ops.exists(TEST_DIR_CONTEXT_ADDRESS2)); + } + + @Test + public void addFullDirContext() throws Exception { + AddKeyStore addKeyStore = new AddKeyStore.Builder(TEST_KEY_STORE_NAME) + .type(TEST_KEY_STORE_TYPE) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_STORE_PASSWORD) + .build()) + .build(); + client.apply(addKeyStore); + AddKeyManager addKeyManager = new AddKeyManager.Builder(TEST_KEY_MNGR_NAME) + .keyStore(TEST_KEY_STORE_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_PASSWORD) + .build()) + .build(); + client.apply(addKeyManager); + AddServerSSLContext addServerSSLContext = new AddServerSSLContext.Builder(TEST_SERVER_SSL_CONTEXT) + .keyManager(TEST_KEY_MNGR_NAME) + .build(); + client.apply(addServerSSLContext); + AddAuthenticationContext addAuthenticationContext + = new AddAuthenticationContext.Builder(TEST_AUTHENTICATION_CONTEXT_NAME) + .build(); + client.apply(addAuthenticationContext); + + AddDirContext addDirContext = new AddDirContext.Builder(TEST_DIR_CONTEXT_NAME) + .url("localhost") + .authenticationLevel(AddDirContext.AuthenticationLevel.STRONG) + .enableConnectionPooling(false) + .referralMode(AddDirContext.ReferralMode.THROW) + .authenticationContext(TEST_AUTHENTICATION_CONTEXT_NAME) + .connectionTimeout(10) + .readTimeout(20) + .module("org.wildfly.security.elytron-private") + .addProperties(new Property("property1", "value1"), + new Property("property2", "value2")) + .build(); + + AddDirContext addDirContext2 = new AddDirContext.Builder(TEST_DIR_CONTEXT_NAME2) + .url("localhost") + .authenticationLevel(AddDirContext.AuthenticationLevel.STRONG) + .enableConnectionPooling(false) + .principal("test-principal") + .referralMode(AddDirContext.ReferralMode.THROW) + .connectionTimeout(10) + .readTimeout(20) + .module("org.wildfly.security.elytron-private") + .sslContext(TEST_SERVER_SSL_CONTEXT) + .addProperties(new Property("property1", "value1"), + new Property("property2", "value2")) + .build(); + + client.apply(addDirContext, addDirContext2); + assertTrue("Dir context should be created", ops.exists(TEST_DIR_CONTEXT_ADDRESS)); + + checkAttribute(TEST_DIR_CONTEXT_ADDRESS, "url", "localhost"); + checkAttribute(TEST_DIR_CONTEXT_ADDRESS, "authentication-level", "STRONG"); + checkAttribute(TEST_DIR_CONTEXT_ADDRESS, "enable-connection-pooling", "false"); + checkAttribute(TEST_DIR_CONTEXT_ADDRESS, "referral-mode", "THROW"); + checkAttribute(TEST_DIR_CONTEXT_ADDRESS, "authentication-context", TEST_AUTHENTICATION_CONTEXT_NAME); + checkAttribute(TEST_DIR_CONTEXT_ADDRESS, "connection-timeout", "10"); + checkAttribute(TEST_DIR_CONTEXT_ADDRESS, "read-timeout", "20"); + checkAttribute(TEST_DIR_CONTEXT_ADDRESS, "module", "org.wildfly.security.elytron-private"); + checkAttribute(TEST_DIR_CONTEXT_ADDRESS, "properties.property1", "value1"); + checkAttribute(TEST_DIR_CONTEXT_ADDRESS, "properties.property2", "value2"); + + checkAttribute(TEST_DIR_CONTEXT_ADDRESS2, "url", "localhost"); + checkAttribute(TEST_DIR_CONTEXT_ADDRESS2, "authentication-level", "STRONG"); + checkAttribute(TEST_DIR_CONTEXT_ADDRESS2, "enable-connection-pooling", "false"); + checkAttribute(TEST_DIR_CONTEXT_ADDRESS2, "principal", "test-principal"); + checkAttribute(TEST_DIR_CONTEXT_ADDRESS2, "referral-mode", "THROW"); + checkAttribute(TEST_DIR_CONTEXT_ADDRESS2, "connection-timeout", "10"); + checkAttribute(TEST_DIR_CONTEXT_ADDRESS2, "read-timeout", "20"); + checkAttribute(TEST_DIR_CONTEXT_ADDRESS2, "module", "org.wildfly.security.elytron-private"); + checkAttribute(TEST_DIR_CONTEXT_ADDRESS2, "ssl-context", TEST_SERVER_SSL_CONTEXT); + checkAttribute(TEST_DIR_CONTEXT_ADDRESS2, "properties.property1", "value1"); + checkAttribute(TEST_DIR_CONTEXT_ADDRESS2, "properties.property2", "value2"); + + } + + @Test + public void addDirContextWithCredentialReference() throws Exception { + AddDirContext addDirContext = new AddDirContext.Builder(TEST_DIR_CONTEXT_NAME) + .url("localhost") + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("somePassword") + .build()) + .build(); + + client.apply(addDirContext); + assertTrue("Dir context should be created", ops.exists(TEST_DIR_CONTEXT_ADDRESS)); + + checkAttribute(TEST_DIR_CONTEXT_ADDRESS, "credential-reference.clear-text", "somePassword"); + } + + @Test(expected = CommandFailedException.class) + public void addDirContextNotAllowed() throws Exception { + AddDirContext addDirContext = new AddDirContext.Builder(TEST_DIR_CONTEXT_NAME) + .url("localhost") + .build(); + + AddDirContext addDirContext2 = new AddDirContext.Builder(TEST_DIR_CONTEXT_NAME) + .url("localhost") + .build(); + + client.apply(addDirContext); + assertTrue("Dir context should be created", ops.exists(TEST_DIR_CONTEXT_ADDRESS)); + client.apply(addDirContext2); + fail("Dir Context CreaperTestDirContext already exists in configuration, exception should be thrown"); + } + + @Test + public void addDirContextAllowed() throws Exception { + AddDirContext addDirContext = new AddDirContext.Builder(TEST_DIR_CONTEXT_NAME) + .url("localhost") + .build(); + + AddDirContext addDirContext2 = new AddDirContext.Builder(TEST_DIR_CONTEXT_NAME) + .url("http://www.example.com/") + .replaceExisting() + .build(); + + client.apply(addDirContext); + assertTrue("Dir context should be created", ops.exists(TEST_DIR_CONTEXT_ADDRESS)); + client.apply(addDirContext2); + assertTrue("Dir context should be created", ops.exists(TEST_DIR_CONTEXT_ADDRESS)); + // check whether it was really rewritten + checkAttribute(TEST_DIR_CONTEXT_ADDRESS, "url", "http://www.example.com/"); + } + + @Test(expected = IllegalArgumentException.class) + public void addDirContext_nullName() throws Exception { + new AddDirContext.Builder(null) + .url("localhost") + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addDirContext_emptyName() throws Exception { + new AddDirContext.Builder("") + .url("localhost") + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addDirContext_nullUrl() throws Exception { + new AddDirContext.Builder(TEST_DIR_CONTEXT_NAME) + .url(null) + .build(); + fail("Creating command with null url should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addDirContext_emptyUrl() throws Exception { + new AddDirContext.Builder(TEST_DIR_CONTEXT_NAME) + .url("") + .build(); + fail("Creating command with empty url should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addDirContext_authenticationContextAndCredentialReference() throws Exception { + new AddDirContext.Builder(TEST_DIR_CONTEXT_NAME) + .url("localhost") + .authenticationContext(TEST_AUTHENTICATION_CONTEXT_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("somePassword") + .build()) + .build(); + fail("Creating command with both authenticationContext and credentialReference should throw exception"); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/domain/AddSecurityDomainOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/domain/AddSecurityDomainOnlineTest.java new file mode 100644 index 00000000..b4a3e81a --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/domain/AddSecurityDomainOnlineTest.java @@ -0,0 +1,398 @@ +package org.wildfly.extras.creaper.commands.elytron.domain; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.commands.elytron.audit.AddFileAuditLog; +import org.wildfly.extras.creaper.commands.elytron.mapper.AddConstantPrincipalTransformer; +import org.wildfly.extras.creaper.commands.elytron.mapper.AddConstantPrincipalDecoder; +import org.wildfly.extras.creaper.commands.elytron.mapper.AddConstantRoleMapper; +import org.wildfly.extras.creaper.commands.elytron.mapper.AddSimplePermissionMapper; +import org.wildfly.extras.creaper.commands.elytron.mapper.AddSimpleRegexRealmMapper; +import org.wildfly.extras.creaper.commands.elytron.mapper.AddSimpleRoleDecoder; +import org.wildfly.extras.creaper.commands.elytron.realm.AddFilesystemRealm; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddSecurityDomainOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_SECURITY_DOMAIN_NAME = "CreaperTestSecurityDomain"; + private static final Address TEST_SECURITY_DOMAIN_ADDRESS = SUBSYSTEM_ADDRESS + .and("security-domain", TEST_SECURITY_DOMAIN_NAME); + private static final String TEST_SECURITY_DOMAIN_NAME2 = "CreaperTestSecurityDomain2"; + private static final Address TEST_SECURITY_DOMAIN_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("security-domain", TEST_SECURITY_DOMAIN_NAME2); + + private static final String TEST_FILESYSTEM_REALM_NAME = "CreaperTestFilesystemRealm"; + private static final Address TEST_FILESYSTEM_REALM_ADDRESS = SUBSYSTEM_ADDRESS + .and("filesystem-realm", TEST_FILESYSTEM_REALM_NAME); + private final AddFilesystemRealm addFilesystemRealm = new AddFilesystemRealm.Builder(TEST_FILESYSTEM_REALM_NAME) + .path("/path/to/filesystem") + .build(); + + private static final String TEST_FILESYSTEM_REALM_NAME2 = "CreaperTestFilesystemRealm2"; + private static final Address TEST_FILESYSTEM_REALM_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("filesystem-realm", TEST_FILESYSTEM_REALM_NAME2); + private final AddFilesystemRealm addFilesystemRealm2 = new AddFilesystemRealm.Builder(TEST_FILESYSTEM_REALM_NAME2) + .path("/path/to/filesystem2") + .build(); + + private static final String TEST_SIMPLE_PERMISSION_MAPPER_NAME = "CreaperTestSimplePermissionMapper"; + private static final Address TEST_SIMPLE_PERMISSION_MAPPER_ADDRESS = SUBSYSTEM_ADDRESS + .and("simple-permission-mapper", TEST_SIMPLE_PERMISSION_MAPPER_NAME); + private final AddSimplePermissionMapper addSimplePermissionMapper + = new AddSimplePermissionMapper.Builder(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .addPermissionMappings(new AddSimplePermissionMapper.PermissionMappingBuilder() + .addPermissions(new AddSimplePermissionMapper.PermissionBuilder() + .className("org.wildfly.security.auth.permission.LoginPermission") + .build()) + .build()) + .build(); + + private static final String TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME = "CreaperTestConstantPrincipalTransformer"; + private static final Address TEST_CONSTANT_PRINCIPAL_TRANSFORMER_ADDRESS = SUBSYSTEM_ADDRESS + .and("constant-principal-transformer", TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME); + private final AddConstantPrincipalTransformer addConstantPrincipalTransformer + = new AddConstantPrincipalTransformer.Builder(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME) + .constant("name1") + .build(); + + private static final String TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2 = "CreaperTestConstantPrincipalTransformer2"; + private static final Address TEST_CONSTANT_PRINCIPAL_TRANSFORMER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("constant-principal-transformer", TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2); + private final AddConstantPrincipalTransformer addConstantPrincipalTransformer2 + = new AddConstantPrincipalTransformer.Builder(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .constant("name2") + .build(); + + private static final String TEST_CONSTANT_PRINCIPAL_DECODER_NAME = "CreaperTestConstantPrincipalDecoder"; + private static final Address TEST_CONSTANT_PRINCIPAL_DECODER_ADDRESS = SUBSYSTEM_ADDRESS + .and("constant-principal-decoder", TEST_CONSTANT_PRINCIPAL_DECODER_NAME); + private final AddConstantPrincipalDecoder addConstantPrincipalDecoder + = new AddConstantPrincipalDecoder.Builder(TEST_CONSTANT_PRINCIPAL_DECODER_NAME) + .constant("role1") + .build(); + + private static final String TEST_SIMPLE_REGEX_REALM_MAPPER_NAME = "CreaperTestSimpleRegexRealmMapper"; + private static final Address TEST_SIMPLE_REGEX_REALM_MAPPER_ADDRESS = SUBSYSTEM_ADDRESS + .and("simple-regex-realm-mapper", TEST_SIMPLE_REGEX_REALM_MAPPER_NAME); + private final AddSimpleRegexRealmMapper addSimpleRegexRealmMapper + = new AddSimpleRegexRealmMapper.Builder(TEST_SIMPLE_REGEX_REALM_MAPPER_NAME) + .pattern("(somePattern)") + .build(); + + private static final String TEST_CONSTANT_ROLE_MAPPER_NAME = "CreaperTestConstantRoleMapper"; + private static final Address TEST_CONSTANT_ROLE_MAPPER_ADDRESS = SUBSYSTEM_ADDRESS + .and("constant-role-mapper", TEST_CONSTANT_ROLE_MAPPER_NAME); + private final AddConstantRoleMapper addConstantRoleMapper + = new AddConstantRoleMapper.Builder(TEST_CONSTANT_ROLE_MAPPER_NAME) + .addRoles("AnyRole") + .build(); + + private static final String TEST_CONSTANT_ROLE_MAPPER_NAME2 = "CreaperTestConstantRoleMapper2"; + private static final Address TEST_CONSTANT_ROLE_MAPPER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("constant-role-mapper", TEST_CONSTANT_ROLE_MAPPER_NAME2); + private final AddConstantRoleMapper addConstantRoleMapper2 + = new AddConstantRoleMapper.Builder(TEST_CONSTANT_ROLE_MAPPER_NAME2) + .addRoles("AnyRole2") + .build(); + + private static final String TEST_SIMPLE_ROLE_DECODER_NAME = "CreaperTestSimpleRoleDecoder"; + private static final Address TEST_SIMPLE_ROLE_DECODER_ADDRESS = SUBSYSTEM_ADDRESS + .and("simple-role-decoder", TEST_SIMPLE_ROLE_DECODER_NAME); + private final AddSimpleRoleDecoder addSimpleRoleDecoder + = new AddSimpleRoleDecoder.Builder(TEST_SIMPLE_ROLE_DECODER_NAME) + .attribute("groups") + .build(); + + private static final String TEST_SIMPLE_ROLE_DECODER_NAME2 = "CreaperTestSimpleRoleDecoder2"; + private static final Address TEST_SIMPLE_ROLE_DECODER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("simple-role-decoder", TEST_SIMPLE_ROLE_DECODER_NAME2); + private final AddSimpleRoleDecoder addSimpleRoleDecoder2 + = new AddSimpleRoleDecoder.Builder(TEST_SIMPLE_ROLE_DECODER_NAME2) + .attribute("groups2") + .build(); + + private static final String TEST_SECURITY_DOMAIN_NAME3 = "CreaperTestSecurityDomain3"; + private static final Address TEST_SECURITY_DOMAIN_ADDRESS3 = SUBSYSTEM_ADDRESS + .and("security-domain", TEST_SECURITY_DOMAIN_NAME3); + private final AddSecurityDomain addSecurityDomain3 = new AddSecurityDomain.Builder(TEST_SECURITY_DOMAIN_NAME3) + .defaultRealm(TEST_FILESYSTEM_REALM_NAME) + .realms(new AddSecurityDomain.RealmBuilder(TEST_FILESYSTEM_REALM_NAME) + .build()) + .build(); + + private static final String TEST_SECURITY_DOMAIN_NAME4 = "CreaperTestSecurityDomain4"; + private static final Address TEST_SECURITY_DOMAIN_ADDRESS4 = SUBSYSTEM_ADDRESS + .and("security-domain", TEST_SECURITY_DOMAIN_NAME4); + private final AddSecurityDomain addSecurityDomain4 = new AddSecurityDomain.Builder(TEST_SECURITY_DOMAIN_NAME4) + .defaultRealm(TEST_FILESYSTEM_REALM_NAME) + .realms(new AddSecurityDomain.RealmBuilder(TEST_FILESYSTEM_REALM_NAME) + .build()) + .build(); + + private static final String TEST_FILE_AUDIT_LOG_NAME = "CreaperTestFileAuditLog"; + private static final Address TEST_FILE_AUDIT_LOG_ADDRESS = SUBSYSTEM_ADDRESS + .and("file-audit-log", TEST_FILE_AUDIT_LOG_NAME); + AddFileAuditLog addFileAuditLog = new AddFileAuditLog.Builder(TEST_FILE_AUDIT_LOG_NAME) + .path("audit.log") + .build(); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_SECURITY_DOMAIN_ADDRESS); + ops.removeIfExists(TEST_SECURITY_DOMAIN_ADDRESS2); + ops.removeIfExists(TEST_SECURITY_DOMAIN_ADDRESS3); + ops.removeIfExists(TEST_SECURITY_DOMAIN_ADDRESS4); + ops.removeIfExists(TEST_FILESYSTEM_REALM_ADDRESS); + ops.removeIfExists(TEST_FILESYSTEM_REALM_ADDRESS2); + ops.removeIfExists(TEST_SIMPLE_PERMISSION_MAPPER_ADDRESS); + ops.removeIfExists(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_ADDRESS); + ops.removeIfExists(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_ADDRESS2); + ops.removeIfExists(TEST_CONSTANT_PRINCIPAL_DECODER_ADDRESS); + ops.removeIfExists(TEST_SIMPLE_REGEX_REALM_MAPPER_ADDRESS); + ops.removeIfExists(TEST_CONSTANT_ROLE_MAPPER_ADDRESS); + ops.removeIfExists(TEST_CONSTANT_ROLE_MAPPER_ADDRESS2); + ops.removeIfExists(TEST_SIMPLE_ROLE_DECODER_ADDRESS); + ops.removeIfExists(TEST_SIMPLE_ROLE_DECODER_ADDRESS2); + ops.removeIfExists(TEST_FILE_AUDIT_LOG_ADDRESS); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleSecurityDomain() throws Exception { + client.apply(addFilesystemRealm); + + AddSecurityDomain addSecurityDomain = new AddSecurityDomain.Builder(TEST_SECURITY_DOMAIN_NAME) + .defaultRealm(TEST_FILESYSTEM_REALM_NAME) + .realms(new AddSecurityDomain.RealmBuilder(TEST_FILESYSTEM_REALM_NAME) + .build()) + .build(); + + client.apply(addSecurityDomain); + + assertTrue("Security domain should be created", ops.exists(TEST_SECURITY_DOMAIN_ADDRESS)); + } + + @Test + public void addTwoSecurityDomains() throws Exception { + client.apply(addFilesystemRealm); + + AddSecurityDomain addSecurityDomain = new AddSecurityDomain.Builder(TEST_SECURITY_DOMAIN_NAME) + .defaultRealm(TEST_FILESYSTEM_REALM_NAME) + .realms(new AddSecurityDomain.RealmBuilder(TEST_FILESYSTEM_REALM_NAME) + .build()) + .build(); + AddSecurityDomain addSecurityDomain2 = new AddSecurityDomain.Builder(TEST_SECURITY_DOMAIN_NAME2) + .defaultRealm(TEST_FILESYSTEM_REALM_NAME) + .realms(new AddSecurityDomain.RealmBuilder(TEST_FILESYSTEM_REALM_NAME) + .build()) + .build(); + + client.apply(addSecurityDomain); + client.apply(addSecurityDomain2); + + assertTrue("Security domain should be created", ops.exists(TEST_SECURITY_DOMAIN_ADDRESS)); + assertTrue("Second security domain should be created", ops.exists(TEST_SECURITY_DOMAIN_ADDRESS2)); + } + + @Test + public void addFullSecurityDomain() throws Exception { + client.apply(addFilesystemRealm); + client.apply(addFilesystemRealm2); + client.apply(addSimplePermissionMapper); + client.apply(addConstantPrincipalTransformer); + client.apply(addConstantPrincipalTransformer2); + client.apply(addConstantPrincipalDecoder); + client.apply(addSimpleRegexRealmMapper); + client.apply(addConstantRoleMapper); + client.apply(addConstantRoleMapper2); + client.apply(addSimpleRoleDecoder); + client.apply(addSimpleRoleDecoder2); + client.apply(addFileAuditLog); + client.apply(addSecurityDomain3); + client.apply(addSecurityDomain4); + AddSecurityDomain addSecurityDomain2 = new AddSecurityDomain.Builder(TEST_SECURITY_DOMAIN_NAME2) + .defaultRealm(TEST_FILESYSTEM_REALM_NAME2) + .realms(new AddSecurityDomain.RealmBuilder(TEST_FILESYSTEM_REALM_NAME2) + .build()) + .build(); + client.apply(addSecurityDomain2); + + AddSecurityDomain addSecurityDomain = new AddSecurityDomain.Builder(TEST_SECURITY_DOMAIN_NAME) + .defaultRealm(TEST_FILESYSTEM_REALM_NAME) + .permissionMapper(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .postRealmPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME) + .preRealmPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .principalDecoder(TEST_CONSTANT_PRINCIPAL_DECODER_NAME) + .realmMapper(TEST_SIMPLE_REGEX_REALM_MAPPER_NAME) + .roleMapper(TEST_CONSTANT_ROLE_MAPPER_NAME) + .trustedSecurityDomains(TEST_SECURITY_DOMAIN_NAME2, TEST_SECURITY_DOMAIN_NAME3) + .outflowAnonymous(true) + .outflowSecurityDomains(TEST_SECURITY_DOMAIN_NAME3, TEST_SECURITY_DOMAIN_NAME4) + .securityEventListener(TEST_FILE_AUDIT_LOG_NAME) + .realms(new AddSecurityDomain.RealmBuilder(TEST_FILESYSTEM_REALM_NAME) + .principalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME) + .roleDecoder(TEST_SIMPLE_ROLE_DECODER_NAME) + .roleMapper(TEST_CONSTANT_ROLE_MAPPER_NAME) + .build(), + new AddSecurityDomain.RealmBuilder(TEST_FILESYSTEM_REALM_NAME2) + .principalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .roleDecoder(TEST_SIMPLE_ROLE_DECODER_NAME2) + .roleMapper(TEST_CONSTANT_ROLE_MAPPER_NAME2) + .build()) + .build(); + + client.apply(addSecurityDomain); + assertTrue("Security domain should be created", ops.exists(TEST_SECURITY_DOMAIN_ADDRESS)); + + checkAttribute(TEST_SECURITY_DOMAIN_ADDRESS, "default-realm", TEST_FILESYSTEM_REALM_NAME); + checkAttribute(TEST_SECURITY_DOMAIN_ADDRESS, "permission-mapper", TEST_SIMPLE_PERMISSION_MAPPER_NAME); + checkAttribute(TEST_SECURITY_DOMAIN_ADDRESS, "post-realm-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME); + checkAttribute(TEST_SECURITY_DOMAIN_ADDRESS, "pre-realm-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2); + checkAttribute(TEST_SECURITY_DOMAIN_ADDRESS, "principal-decoder", TEST_CONSTANT_PRINCIPAL_DECODER_NAME); + checkAttribute(TEST_SECURITY_DOMAIN_ADDRESS, "realm-mapper", TEST_SIMPLE_REGEX_REALM_MAPPER_NAME); + checkAttribute(TEST_SECURITY_DOMAIN_ADDRESS, "role-mapper", TEST_CONSTANT_ROLE_MAPPER_NAME); + checkAttribute(TEST_SECURITY_DOMAIN_ADDRESS, "trusted-security-domains[0]", TEST_SECURITY_DOMAIN_NAME2); + checkAttribute(TEST_SECURITY_DOMAIN_ADDRESS, "trusted-security-domains[1]", TEST_SECURITY_DOMAIN_NAME3); + checkAttribute(TEST_SECURITY_DOMAIN_ADDRESS, "outflow-anonymous", "true"); + checkAttribute(TEST_SECURITY_DOMAIN_ADDRESS, "outflow-security-domains[0]", TEST_SECURITY_DOMAIN_NAME3); + checkAttribute(TEST_SECURITY_DOMAIN_ADDRESS, "outflow-security-domains[1]", TEST_SECURITY_DOMAIN_NAME4); + checkAttribute(TEST_SECURITY_DOMAIN_ADDRESS, "security-event-listener", TEST_FILE_AUDIT_LOG_NAME); + + checkAttribute(TEST_SECURITY_DOMAIN_ADDRESS, "realms[0].realm", TEST_FILESYSTEM_REALM_NAME); + checkAttribute(TEST_SECURITY_DOMAIN_ADDRESS, "realms[0].principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME); + checkAttribute(TEST_SECURITY_DOMAIN_ADDRESS, "realms[0].role-decoder", TEST_SIMPLE_ROLE_DECODER_NAME); + checkAttribute(TEST_SECURITY_DOMAIN_ADDRESS, "realms[0].role-mapper", TEST_CONSTANT_ROLE_MAPPER_NAME); + + checkAttribute(TEST_SECURITY_DOMAIN_ADDRESS, "realms[1].realm", TEST_FILESYSTEM_REALM_NAME2); + checkAttribute(TEST_SECURITY_DOMAIN_ADDRESS, "realms[1].principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2); + checkAttribute(TEST_SECURITY_DOMAIN_ADDRESS, "realms[1].role-decoder", TEST_SIMPLE_ROLE_DECODER_NAME2); + checkAttribute(TEST_SECURITY_DOMAIN_ADDRESS, "realms[1].role-mapper", TEST_CONSTANT_ROLE_MAPPER_NAME2); + } + + @Test(expected = CommandFailedException.class) + public void addExistSecurityDomainNotAllowed() throws Exception { + client.apply(addFilesystemRealm); + client.apply(addFilesystemRealm2); + + AddSecurityDomain addSecurityDomain = new AddSecurityDomain.Builder(TEST_SECURITY_DOMAIN_NAME) + .defaultRealm(TEST_FILESYSTEM_REALM_NAME) + .realms(new AddSecurityDomain.RealmBuilder(TEST_FILESYSTEM_REALM_NAME) + .build()) + .build(); + + AddSecurityDomain addSecurityDomain2 = new AddSecurityDomain.Builder(TEST_SECURITY_DOMAIN_NAME) + .defaultRealm(TEST_FILESYSTEM_REALM_NAME2) + .realms(new AddSecurityDomain.RealmBuilder(TEST_FILESYSTEM_REALM_NAME2) + .build()) + .build(); + + client.apply(addSecurityDomain); + assertTrue("Security domain should be created", ops.exists(TEST_SECURITY_DOMAIN_ADDRESS)); + client.apply(addSecurityDomain2); + fail("Security domain CreaperTestSecurityDomain already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistSecurityDomainAllowed() throws Exception { + client.apply(addFilesystemRealm); + client.apply(addFilesystemRealm2); + + AddSecurityDomain addSecurityDomain = new AddSecurityDomain.Builder(TEST_SECURITY_DOMAIN_NAME) + .defaultRealm(TEST_FILESYSTEM_REALM_NAME) + .realms(new AddSecurityDomain.RealmBuilder(TEST_FILESYSTEM_REALM_NAME) + .build()) + .build(); + + AddSecurityDomain addSecurityDomain2 = new AddSecurityDomain.Builder(TEST_SECURITY_DOMAIN_NAME) + .defaultRealm(TEST_FILESYSTEM_REALM_NAME2) + .realms(new AddSecurityDomain.RealmBuilder(TEST_FILESYSTEM_REALM_NAME2) + .build()) + .replaceExisting() + .build(); + + client.apply(addSecurityDomain); + assertTrue("Security domain should be created", ops.exists(TEST_SECURITY_DOMAIN_ADDRESS)); + client.apply(addSecurityDomain2); + assertTrue("Security domain should be created", ops.exists(TEST_SECURITY_DOMAIN_ADDRESS)); + // check whether it was really rewritten + checkAttribute(TEST_SECURITY_DOMAIN_ADDRESS, "default-realm", TEST_FILESYSTEM_REALM_NAME2); + } + + @Test(expected = IllegalArgumentException.class) + public void addSecurityDomain_nullName() throws Exception { + new AddSecurityDomain.Builder(null) + .defaultRealm(TEST_FILESYSTEM_REALM_NAME) + .realms(new AddSecurityDomain.RealmBuilder(TEST_FILESYSTEM_REALM_NAME) + .build()) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSecurityDomain_emptyName() throws Exception { + new AddSecurityDomain.Builder("") + .defaultRealm(TEST_FILESYSTEM_REALM_NAME) + .realms(new AddSecurityDomain.RealmBuilder(TEST_FILESYSTEM_REALM_NAME) + .build()) + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSecurityDomain_nullRealms() throws Exception { + new AddSecurityDomain.Builder(TEST_SECURITY_DOMAIN_NAME) + .defaultRealm(TEST_FILESYSTEM_REALM_NAME) + .realms(null) + .build(); + fail("Creating command with null realms should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSecurityDomain_noRealms() throws Exception { + new AddSecurityDomain.Builder(TEST_SECURITY_DOMAIN_NAME) + .defaultRealm(TEST_FILESYSTEM_REALM_NAME) + .build(); + fail("Creating command with no realms should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSecurityDomain_emptyRealms() throws Exception { + new AddSecurityDomain.Builder(TEST_SECURITY_DOMAIN_NAME) + .defaultRealm(TEST_FILESYSTEM_REALM_NAME) + .realms() + .build(); + fail("Creating command with empty realms should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSecurityDomain_nullRealmsRealmName() throws Exception { + new AddSecurityDomain.Builder(TEST_SECURITY_DOMAIN_NAME) + .defaultRealm(TEST_FILESYSTEM_REALM_NAME) + .realms(new AddSecurityDomain.RealmBuilder(null) + .build()) + .build(); + fail("Creating command with null name of realm in realms should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSecurityDomain_emptyRealmsRealmName() throws Exception { + new AddSecurityDomain.Builder(TEST_SECURITY_DOMAIN_NAME) + .defaultRealm(TEST_FILESYSTEM_REALM_NAME) + .realms(new AddSecurityDomain.RealmBuilder("") + .build()) + .build(); + fail("Creating command with empty name of realm in realms should throw exception"); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/http/AddAggregateHttpServerMechanismFactoryOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/http/AddAggregateHttpServerMechanismFactoryOnlineTest.java new file mode 100644 index 00000000..5b222c7f --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/http/AddAggregateHttpServerMechanismFactoryOnlineTest.java @@ -0,0 +1,221 @@ +package org.wildfly.extras.creaper.commands.elytron.http; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddAggregateHttpServerMechanismFactoryOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_SERVER_MECHANISM_FACTORY_NAME + = "CreaperTestAggregateHttpServerMechanismFactory"; + private static final Address TEST_SERVER_MECHANISM_FACTORY_ADDRESS = SUBSYSTEM_ADDRESS + .and("aggregate-http-server-mechanism-factory", TEST_SERVER_MECHANISM_FACTORY_NAME); + private static final String TEST_SERVER_MECHANISM_FACTORY_NAME2 + = "CreaperTestAggregateHttpServerMechanismFactory2"; + private static final Address TEST_SERVER_MECHANISM_FACTORY_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("aggregate-http-server-mechanism-factory", TEST_SERVER_MECHANISM_FACTORY_NAME2); + + private static final String TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME + = "CreaperTestProviderHttpServerMechanismFactory"; + private static final Address TEST_PROVIDER_SERVER_MECHANISM_FACTORY_ADDRESS = SUBSYSTEM_ADDRESS + .and("provider-http-server-mechanism-factory", TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME); + private final AddProviderHttpServerMechanismFactory addProviderHttpServerMechanismFactory + = new AddProviderHttpServerMechanismFactory.Builder(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME) + .build(); + private static final String TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME2 + = "CreaperTestProviderHttpServerMechanismFactory2"; + private static final Address TEST_PROVIDER_SERVER_MECHANISM_FACTORY_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("provider-http-server-mechanism-factory", TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME2); + private final AddProviderHttpServerMechanismFactory addProviderHttpServerMechanismFactory2 + = new AddProviderHttpServerMechanismFactory.Builder(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME2) + .build(); + private static final String TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME3 + = "CreaperTestProviderHttpServerMechanismFactory3"; + private static final Address TEST_PROVIDER_SERVER_MECHANISM_FACTORY_ADDRESS3 = SUBSYSTEM_ADDRESS + .and("provider-http-server-mechanism-factory", TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME3); + private final AddProviderHttpServerMechanismFactory addProviderHttpServerMechanismFactory3 + = new AddProviderHttpServerMechanismFactory.Builder(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME3) + .build(); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS); + ops.removeIfExists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS2); + ops.removeIfExists(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_ADDRESS); + ops.removeIfExists(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_ADDRESS2); + ops.removeIfExists(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_ADDRESS3); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleAggregateHttpServerMechanismFactory() throws Exception { + client.apply(addProviderHttpServerMechanismFactory); + client.apply(addProviderHttpServerMechanismFactory2); + + AddAggregateHttpServerMechanismFactory addAggregateHttpServerMechanismFactory + = new AddAggregateHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .addHttpServerMechanismFactories(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME, + TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME2) + .build(); + + client.apply(addAggregateHttpServerMechanismFactory); + + assertTrue("Aggregate http server mechanism factory should be created", + ops.exists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS)); + } + + @Test + public void addTwoAggregateHttpServerMechanismFactories() throws Exception { + client.apply(addProviderHttpServerMechanismFactory); + client.apply(addProviderHttpServerMechanismFactory2); + + AddAggregateHttpServerMechanismFactory addAggregateHttpServerMechanismFactory + = new AddAggregateHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .addHttpServerMechanismFactories(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME, + TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME2) + .build(); + + AddAggregateHttpServerMechanismFactory addAggregateHttpServerMechanismFactory2 + = new AddAggregateHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME2) + .addHttpServerMechanismFactories(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME, + TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME2) + .build(); + client.apply(addAggregateHttpServerMechanismFactory); + client.apply(addAggregateHttpServerMechanismFactory2); + + assertTrue("Aggregate http server mechanism factory should be created", + ops.exists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS)); + assertTrue("Second aggregate http server mechanism factory should be created", + ops.exists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS2)); + } + + @Test + public void addFullAggregateHttpServerMechanismFactory() throws Exception { + client.apply(addProviderHttpServerMechanismFactory); + client.apply(addProviderHttpServerMechanismFactory2); + client.apply(addProviderHttpServerMechanismFactory3); + + AddAggregateHttpServerMechanismFactory addAggregateHttpServerMechanismFactory + = new AddAggregateHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .addHttpServerMechanismFactories(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME, + TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME2, + TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME3) + .build(); + + client.apply(addAggregateHttpServerMechanismFactory); + + assertTrue("Aggregate http server mechanism factory should be created", + ops.exists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS)); + + checkAttribute(TEST_SERVER_MECHANISM_FACTORY_ADDRESS, "http-server-mechanism-factories[0]", + TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME); + checkAttribute(TEST_SERVER_MECHANISM_FACTORY_ADDRESS, "http-server-mechanism-factories[1]", + TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME2); + checkAttribute(TEST_SERVER_MECHANISM_FACTORY_ADDRESS, "http-server-mechanism-factories[2]", + TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME3); + } + + @Test(expected = CommandFailedException.class) + public void addExistAggregateHttpServerMechanismFactoryNotAllowed() throws Exception { + client.apply(addProviderHttpServerMechanismFactory); + client.apply(addProviderHttpServerMechanismFactory2); + + AddAggregateHttpServerMechanismFactory addAggregateHttpServerMechanismFactory + = new AddAggregateHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .addHttpServerMechanismFactories(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME, + TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME2) + .build(); + + AddAggregateHttpServerMechanismFactory addAggregateHttpServerMechanismFactory2 + = new AddAggregateHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .addHttpServerMechanismFactories(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME, + TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME3) + .build(); + + client.apply(addAggregateHttpServerMechanismFactory); + assertTrue("Aggregate http server mechanism factory should be created", + ops.exists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS)); + client.apply(addAggregateHttpServerMechanismFactory2); + fail("Aggregate http server mechanism factory CreaperTestAggregateHttpServerMechanismFactory already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistAggregateHttpServerMechanismFactoryAllowed() throws Exception { + client.apply(addProviderHttpServerMechanismFactory); + client.apply(addProviderHttpServerMechanismFactory2); + client.apply(addProviderHttpServerMechanismFactory3); + + AddAggregateHttpServerMechanismFactory addAggregateHttpServerMechanismFactory + = new AddAggregateHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .addHttpServerMechanismFactories(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME, + TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME2) + .build(); + + AddAggregateHttpServerMechanismFactory addAggregateHttpServerMechanismFactory2 + = new AddAggregateHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .addHttpServerMechanismFactories(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME, + TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME3) + .replaceExisting() + .build(); + + client.apply(addAggregateHttpServerMechanismFactory); + assertTrue("Aggregate http server mechanism factory should be created", + ops.exists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS)); + client.apply(addAggregateHttpServerMechanismFactory2); + assertTrue("Aggregate http server mechanism factory should be created", + ops.exists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS)); + // check whether it was really rewritten + checkAttribute(TEST_SERVER_MECHANISM_FACTORY_ADDRESS, "http-server-mechanism-factories[1]", + TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME3); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregateHttpServerMechanismFactory_nullName() throws Exception { + new AddAggregateHttpServerMechanismFactory.Builder(null) + .addHttpServerMechanismFactories(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME, + TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME2) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregateHttpServerMechanismFactory_emptyName() throws Exception { + new AddAggregateHttpServerMechanismFactory.Builder("") + .addHttpServerMechanismFactories(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME, + TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME2) + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregateHttpServerMechanismFactory_nullHttpServerMechanismFactories() throws Exception { + new AddAggregateHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .addHttpServerMechanismFactories(null) + .build(); + fail("Creating command with null http-server-mechanism-factories should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregateHttpServerMechanismFactory_emptyHttpServerMechanismFactories() throws Exception { + new AddAggregateHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .addHttpServerMechanismFactories("") + .build(); + fail("Creating command with empty http-server-mechanism-factories should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregateHttpServerMechanismFactory_oneHttpServerMechanismFactories() throws Exception { + new AddAggregateHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .addHttpServerMechanismFactories(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME) + .build(); + fail("Creating command with only one http-server-mechanism-factories should throw exception"); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/http/AddConfigurableHttpServerMechanismFactoryOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/http/AddConfigurableHttpServerMechanismFactoryOnlineTest.java new file mode 100644 index 00000000..81d71ebc --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/http/AddConfigurableHttpServerMechanismFactoryOnlineTest.java @@ -0,0 +1,230 @@ +package org.wildfly.extras.creaper.commands.elytron.http; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.commands.elytron.Property; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddConfigurableHttpServerMechanismFactoryOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_SERVER_MECHANISM_FACTORY_NAME + = "CreaperTestConfigurableHttpServerMechanismFactory"; + private static final Address TEST_SERVER_MECHANISM_FACTORY_ADDRESS = SUBSYSTEM_ADDRESS + .and("configurable-http-server-mechanism-factory", TEST_SERVER_MECHANISM_FACTORY_NAME); + private static final String TEST_SERVER_MECHANISM_FACTORY_NAME2 + = "CreaperTestConfigurableHttpServerMechanismFactory2"; + private static final Address TEST_SERVER_MECHANISM_FACTORY_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("configurable-http-server-mechanism-factory", TEST_SERVER_MECHANISM_FACTORY_NAME2); + + private static final String TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME + = "CreaperTestProviderHttpServerMechanismFactory"; + private static final Address TEST_PROVIDER_SERVER_MECHANISM_FACTORY_ADDRESS = SUBSYSTEM_ADDRESS + .and("provider-http-server-mechanism-factory", TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME); + private final AddProviderHttpServerMechanismFactory addProviderHttpServerMechanismFactory + = new AddProviderHttpServerMechanismFactory.Builder(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME) + .build(); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS); + ops.removeIfExists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS2); + ops.removeIfExists(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_ADDRESS); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleConfigurableHttpServerMechanismFactory() throws Exception { + client.apply(addProviderHttpServerMechanismFactory); + + AddConfigurableHttpServerMechanismFactory addConfigurableHttpServerMechanismFactory + = new AddConfigurableHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .httpServerMechanismFactory(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME) + .build(); + + client.apply(addConfigurableHttpServerMechanismFactory); + + assertTrue("Configurable http server mechanism factory should be created", + ops.exists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS)); + } + + @Test + public void addTwoConfigurableHttpServerMechanismFactories() throws Exception { + client.apply(addProviderHttpServerMechanismFactory); + + AddConfigurableHttpServerMechanismFactory addConfigurableHttpServerMechanismFactory + = new AddConfigurableHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .httpServerMechanismFactory(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME) + .build(); + + AddConfigurableHttpServerMechanismFactory addConfigurableHttpServerMechanismFactory2 + = new AddConfigurableHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME2) + .httpServerMechanismFactory(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME) + .build(); + + client.apply(addConfigurableHttpServerMechanismFactory); + client.apply(addConfigurableHttpServerMechanismFactory2); + + assertTrue("Configurable http server mechanism factory should be created", + ops.exists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS)); + assertTrue("Second configurable http server mechanism factory should be created", + ops.exists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS2)); + } + + @Test + public void addFullConfigurableHttpServerMechanismFactory() throws Exception { + client.apply(addProviderHttpServerMechanismFactory); + + AddConfigurableHttpServerMechanismFactory addConfigurableHttpServerMechanismFactory + = new AddConfigurableHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .httpServerMechanismFactory(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME) + .addFilters(new AddConfigurableHttpServerMechanismFactory.FilterBuilder() + .patternFilter("somePattern") + .enabling(false) + .build(), + new AddConfigurableHttpServerMechanismFactory.FilterBuilder() + .patternFilter("somePattern2") + .build()) + .addProperties(new Property("a", "b"), + new Property("c", "d")) + .build(); + + client.apply(addConfigurableHttpServerMechanismFactory); + + assertTrue("Configurable http server mechanism factory should be created", + ops.exists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS)); + + checkAttribute(TEST_SERVER_MECHANISM_FACTORY_ADDRESS, "http-server-mechanism-factory", + TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME); + checkAttribute(TEST_SERVER_MECHANISM_FACTORY_ADDRESS, "filters[0].pattern-filter", "somePattern"); + checkAttribute(TEST_SERVER_MECHANISM_FACTORY_ADDRESS, "filters[0].enabling", "false"); + checkAttribute(TEST_SERVER_MECHANISM_FACTORY_ADDRESS, "filters[1].pattern-filter", "somePattern2"); + checkAttribute(TEST_SERVER_MECHANISM_FACTORY_ADDRESS, "properties.a", "b"); + checkAttribute(TEST_SERVER_MECHANISM_FACTORY_ADDRESS, "properties.c", "d"); + } + + @Test(expected = CommandFailedException.class) + public void addExistConfigurableHttpServerMechanismFactoryNotAllowed() throws Exception { + client.apply(addProviderHttpServerMechanismFactory); + + AddConfigurableHttpServerMechanismFactory addConfigurableHttpServerMechanismFactory + = new AddConfigurableHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .httpServerMechanismFactory(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME) + .addProperties(new Property("a", "b")) + .build(); + + AddConfigurableHttpServerMechanismFactory addConfigurableHttpServerMechanismFactory2 + = new AddConfigurableHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .httpServerMechanismFactory(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME) + .addProperties(new Property("c", "d")) + .build(); + + client.apply(addConfigurableHttpServerMechanismFactory); + assertTrue("Configurable http server mechanism factory should be created", + ops.exists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS)); + client.apply(addConfigurableHttpServerMechanismFactory2); + fail("Configurable http server mechanism factory CreaperTestConfigurableHttpServerMechanismFactory already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistConfigurableHttpServerMechanismFactoryAllowed() throws Exception { + client.apply(addProviderHttpServerMechanismFactory); + + AddConfigurableHttpServerMechanismFactory addConfigurableHttpServerMechanismFactory + = new AddConfigurableHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .httpServerMechanismFactory(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME) + .addProperties(new Property("a", "b")) + .build(); + + AddConfigurableHttpServerMechanismFactory addConfigurableHttpServerMechanismFactory2 + = new AddConfigurableHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .httpServerMechanismFactory(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME) + .addProperties(new Property("c", "d")) + .replaceExisting() + .build(); + + client.apply(addConfigurableHttpServerMechanismFactory); + assertTrue("Configurable http server mechanism factory should be created", + ops.exists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS)); + client.apply(addConfigurableHttpServerMechanismFactory2); + assertTrue("Configurable http server mechanism factory should be created", + ops.exists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS)); + // check whether it was really rewritten + checkAttribute(TEST_SERVER_MECHANISM_FACTORY_ADDRESS, "properties.c", "d"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConfigurableHttpServerMechanismFactory_nullName() throws Exception { + new AddConfigurableHttpServerMechanismFactory.Builder(null) + .httpServerMechanismFactory(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConfigurableHttpServerMechanismFactory_emptyName() throws Exception { + new AddConfigurableHttpServerMechanismFactory.Builder("") + .httpServerMechanismFactory(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME) + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConfigurableHttpServerMechanismFactory_nullHttpServerMechanismFactory() throws Exception { + new AddConfigurableHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .httpServerMechanismFactory(null) + .build(); + fail("Creating command with null http-server-mechanism-factory should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConfigurableHttpServerMechanismFactory_emptyHttpServerMechanismFactory() throws Exception { + new AddConfigurableHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .httpServerMechanismFactory("") + .build(); + fail("Creating command with empty http-server-mechanism-factory should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConfigurableHttpServerMechanismFactory_nullPatternFilter() throws Exception { + new AddConfigurableHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .httpServerMechanismFactory(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME) + .addFilters(new AddConfigurableHttpServerMechanismFactory.FilterBuilder().patternFilter(null).build()) + .build(); + fail("Creating command with null pattern-filter in filters should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConfigurableHttpServerMechanismFactory_emptyPatternFilter() throws Exception { + new AddConfigurableHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .httpServerMechanismFactory(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME) + .addFilters(new AddConfigurableHttpServerMechanismFactory.FilterBuilder().patternFilter("").build()) + .build(); + fail("Creating command with empty pattern-filter in filters should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConfigurableHttpServerMechanismFactory_nullFilters() throws Exception { + new AddConfigurableHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .httpServerMechanismFactory(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME) + .addFilters(null) + .build(); + fail("Creating command with null filters should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConfigurableHttpServerMechanismFactory_nullProperties() throws Exception { + new AddConfigurableHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .httpServerMechanismFactory(TEST_PROVIDER_SERVER_MECHANISM_FACTORY_NAME) + .addProperties(null) + .build(); + fail("Creating command with null properties should throw exception"); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/http/AddHttpAuthenticationFactoryOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/http/AddHttpAuthenticationFactoryOnlineTest.java new file mode 100644 index 00000000..3b6c55d5 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/http/AddHttpAuthenticationFactoryOnlineTest.java @@ -0,0 +1,473 @@ +package org.wildfly.extras.creaper.commands.elytron.http; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.commands.elytron.Mechanism; +import org.wildfly.extras.creaper.commands.elytron.credfactory.AddKerberosSecurityFactory; +import org.wildfly.extras.creaper.commands.elytron.domain.AddSecurityDomain; +import org.wildfly.extras.creaper.commands.elytron.mapper.AddConstantPrincipalTransformer; +import org.wildfly.extras.creaper.commands.elytron.mapper.AddSimpleRegexRealmMapper; +import org.wildfly.extras.creaper.commands.elytron.realm.AddFilesystemRealm; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddHttpAuthenticationFactoryOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_AUTHENTICATION_FACTORY_NAME + = "CreaperTestHttpAuthenticationFactory"; + private static final Address TEST_AUTHENTICATION_FACTORY_ADDRESS = SUBSYSTEM_ADDRESS + .and("http-authentication-factory", TEST_AUTHENTICATION_FACTORY_NAME); + private static final String TEST_AUTHENTICATION_FACTORY_NAME2 + = "CreaperTestHttpAuthenticationFactory2"; + private static final Address TEST_AUTHENTICATION_FACTORY_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("http-authentication-factory", TEST_AUTHENTICATION_FACTORY_NAME2); + + private static final String TEST_FILESYSTEM_REALM_NAME = "CreaperTestFilesystemRealm"; + private static final Address TEST_FILESYSTEM_REALM_ADDRESS = SUBSYSTEM_ADDRESS + .and("filesystem-realm", TEST_FILESYSTEM_REALM_NAME); + private final AddFilesystemRealm addFilesystemRealm = new AddFilesystemRealm.Builder(TEST_FILESYSTEM_REALM_NAME) + .path("/path/to/filesystem") + .build(); + + private static final String TEST_FILESYSTEM_REALM_NAME2 = "CreaperTestFilesystemRealm2"; + private static final Address TEST_FILESYSTEM_REALM_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("filesystem-realm", TEST_FILESYSTEM_REALM_NAME2); + private final AddFilesystemRealm addFilesystemRealm2 = new AddFilesystemRealm.Builder(TEST_FILESYSTEM_REALM_NAME2) + .path("/path/to/filesystem") + .build(); + + private static final String TEST_SECURITY_DOMAIN_NAME = "CreaperTestSecurityDomain"; + private static final Address TEST_SECURITY_DOMAIN_ADDRESS = SUBSYSTEM_ADDRESS + .and("security-domain", TEST_SECURITY_DOMAIN_NAME); + private final AddSecurityDomain addSecurityDomain = new AddSecurityDomain.Builder(TEST_SECURITY_DOMAIN_NAME) + .defaultRealm(TEST_FILESYSTEM_REALM_NAME) + .realms(new AddSecurityDomain.RealmBuilder(TEST_FILESYSTEM_REALM_NAME) + .build()) + .build(); + + private static final String TEST_SERVER_MECHANISM_FACTORY_NAME + = "CreaperTestProviderHttpServerMechanismFactory"; + private static final Address TEST_SERVER_MECHANISM_FACTORY_ADDRESS = SUBSYSTEM_ADDRESS + .and("provider-http-server-mechanism-factory", TEST_SERVER_MECHANISM_FACTORY_NAME); + private final AddProviderHttpServerMechanismFactory addProviderHttpServerMechanismFactory + = new AddProviderHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .build(); + + private static final String TEST_SERVER_MECHANISM_FACTORY_NAME2 + = "CreaperTestProviderHttpServerMechanismFactory2"; + private static final Address TEST_SERVER_MECHANISM_FACTORY_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("provider-http-server-mechanism-factory", TEST_SERVER_MECHANISM_FACTORY_NAME2); + private final AddProviderHttpServerMechanismFactory addProviderHttpServerMechanismFactory2 + = new AddProviderHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME2) + .build(); + + private static final String TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME = "CreaperTestConstantPrincipalTransformer"; + private static final Address TEST_CONSTANT_PRINCIPAL_TRANSFORMER_ADDRESS = SUBSYSTEM_ADDRESS + .and("constant-principal-transformer", TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME); + private final AddConstantPrincipalTransformer addConstantPrincipalTransformer + = new AddConstantPrincipalTransformer.Builder(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME) + .constant("name1") + .build(); + + private static final String TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2 = "CreaperTestConstantPrincipalTransformer2"; + private static final Address TEST_CONSTANT_PRINCIPAL_TRANSFORMER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("constant-principal-transformer", TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2); + private final AddConstantPrincipalTransformer addConstantPrincipalTransformer2 + = new AddConstantPrincipalTransformer.Builder(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .constant("name2") + .build(); + + private static final String TEST_SIMPLE_REGEX_REALM_MAPPER_NAME = "CreaperTestSimpleRegexRealmMapper"; + private static final Address TEST_SIMPLE_REGEX_REALM_MAPPER_ADDRESS = SUBSYSTEM_ADDRESS + .and("simple-regex-realm-mapper", TEST_SIMPLE_REGEX_REALM_MAPPER_NAME); + private final AddSimpleRegexRealmMapper addSimpleRegexRealmMapper + = new AddSimpleRegexRealmMapper.Builder(TEST_SIMPLE_REGEX_REALM_MAPPER_NAME) + .pattern("(somePattern)") + .build(); + + private static final String TEST_SIMPLE_REGEX_REALM_MAPPER_NAME2 = "CreaperTestSimpleRegexRealmMapper2"; + private static final Address TEST_SIMPLE_REGEX_REALM_MAPPER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("simple-regex-realm-mapper", TEST_SIMPLE_REGEX_REALM_MAPPER_NAME2); + private final AddSimpleRegexRealmMapper addSimpleRegexRealmMapper2 + = new AddSimpleRegexRealmMapper.Builder(TEST_SIMPLE_REGEX_REALM_MAPPER_NAME2) + .pattern("(somePattern2)") + .build(); + + private static final String TEST_KERBEROS_SECURITY_FACTORY_NAME = "CreaperTestKerberosSecurityFactory"; + private static final Address TEST_KERBEROS_SECURITY_FACTORY_ADDRESS = SUBSYSTEM_ADDRESS + .and("kerberos-security-factory", TEST_KERBEROS_SECURITY_FACTORY_NAME); + private final AddKerberosSecurityFactory addKerberosSecurityFactory + = new AddKerberosSecurityFactory.Builder(TEST_KERBEROS_SECURITY_FACTORY_NAME) + .principal("principal1") + .path("/path/to/keytab") + .mechanismOIDs("1.2.840.113554.1.2.2") + .build(); + + private static final String TEST_KERBEROS_SECURITY_FACTORY_NAME2 = "CreaperTestKerberosSecurityFactory2"; + private static final Address TEST_KERBEROS_SECURITY_FACTORY_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("kerberos-security-factory", TEST_KERBEROS_SECURITY_FACTORY_NAME2); + private final AddKerberosSecurityFactory addKerberosSecurityFactory2 + = new AddKerberosSecurityFactory.Builder(TEST_KERBEROS_SECURITY_FACTORY_NAME2) + .principal("principal2") + .path("/path/to/keytab") + .mechanismOIDs("1.2.840.113554.1.2.2") + .build(); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_AUTHENTICATION_FACTORY_ADDRESS); + ops.removeIfExists(TEST_AUTHENTICATION_FACTORY_ADDRESS2); + ops.removeIfExists(TEST_SECURITY_DOMAIN_ADDRESS); + ops.removeIfExists(TEST_FILESYSTEM_REALM_ADDRESS); + ops.removeIfExists(TEST_FILESYSTEM_REALM_ADDRESS2); + ops.removeIfExists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS); + ops.removeIfExists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS2); + ops.removeIfExists(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_ADDRESS); + ops.removeIfExists(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_ADDRESS2); + ops.removeIfExists(TEST_SIMPLE_REGEX_REALM_MAPPER_ADDRESS); + ops.removeIfExists(TEST_SIMPLE_REGEX_REALM_MAPPER_ADDRESS2); + ops.removeIfExists(TEST_KERBEROS_SECURITY_FACTORY_ADDRESS); + ops.removeIfExists(TEST_KERBEROS_SECURITY_FACTORY_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleHttpAuthenticationFactory() throws Exception { + client.apply(addFilesystemRealm); + client.apply(addSecurityDomain); + client.apply(addProviderHttpServerMechanismFactory); + + AddHttpAuthenticationFactory addHttpAuthenticationFactory + = new AddHttpAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .httpServerMechanismFactory(TEST_SERVER_MECHANISM_FACTORY_NAME) + .build(); + + client.apply(addHttpAuthenticationFactory); + + assertTrue("Http authentication factory should be created", ops.exists(TEST_AUTHENTICATION_FACTORY_ADDRESS)); + } + + @Test + public void addTwoHttpAuthenticationFactories() throws Exception { + client.apply(addFilesystemRealm); + client.apply(addSecurityDomain); + client.apply(addProviderHttpServerMechanismFactory); + + AddHttpAuthenticationFactory addHttpAuthenticationFactory + = new AddHttpAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .httpServerMechanismFactory(TEST_SERVER_MECHANISM_FACTORY_NAME) + .build(); + + AddHttpAuthenticationFactory addHttpAuthenticationFactory2 + = new AddHttpAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME2) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .httpServerMechanismFactory(TEST_SERVER_MECHANISM_FACTORY_NAME) + .build(); + + client.apply(addHttpAuthenticationFactory); + client.apply(addHttpAuthenticationFactory2); + + assertTrue("Http authentication factory should be created", ops.exists(TEST_AUTHENTICATION_FACTORY_ADDRESS)); + assertTrue("Second http authentication factory should be created", + ops.exists(TEST_AUTHENTICATION_FACTORY_ADDRESS2)); + } + + @Test + public void addFullHttpAuthenticationFactory() throws Exception { + client.apply(addFilesystemRealm); + client.apply(addFilesystemRealm2); + client.apply(addSecurityDomain); + client.apply(addProviderHttpServerMechanismFactory); + client.apply(addConstantPrincipalTransformer); + client.apply(addConstantPrincipalTransformer2); + client.apply(addSimpleRegexRealmMapper); + client.apply(addSimpleRegexRealmMapper2); + client.apply(addKerberosSecurityFactory); + client.apply(addKerberosSecurityFactory2); + + AddHttpAuthenticationFactory addHttpAuthenticationFactory + = new AddHttpAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .httpServerMechanismFactory(TEST_SERVER_MECHANISM_FACTORY_NAME) + .addMechanismConfigurations(new Mechanism.Builder() + .credentialSecurityFactory(TEST_KERBEROS_SECURITY_FACTORY_NAME) + .mechanismName("someMechanismName") + .hostName("someHostName") + .protocol("someProtocol") + .preRealmPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME) + .postRealmPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .finalPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME) + .realmMapper(TEST_SIMPLE_REGEX_REALM_MAPPER_NAME) + .addMechanismRealmConfigurations(new Mechanism.MechanismRealmBuilder() + .realmName(TEST_FILESYSTEM_REALM_NAME) + .preRealmPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME) + .postRealmPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .finalPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME) + .realmMapper(TEST_SIMPLE_REGEX_REALM_MAPPER_NAME) + .build(), + new Mechanism.MechanismRealmBuilder() + .realmName(TEST_FILESYSTEM_REALM_NAME2) + .preRealmPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .postRealmPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME) + .finalPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .realmMapper(TEST_SIMPLE_REGEX_REALM_MAPPER_NAME2) + .build()) + .build(), + new Mechanism.Builder() + .credentialSecurityFactory(TEST_KERBEROS_SECURITY_FACTORY_NAME2) + .mechanismName("someMechanismName2") + .hostName("someHostName2") + .protocol("someProtocol2") + .preRealmPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .postRealmPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME) + .finalPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .realmMapper(TEST_SIMPLE_REGEX_REALM_MAPPER_NAME2) + .addMechanismRealmConfigurations(new Mechanism.MechanismRealmBuilder() + .realmName(TEST_FILESYSTEM_REALM_NAME2) + .preRealmPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .postRealmPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .finalPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .realmMapper(TEST_SIMPLE_REGEX_REALM_MAPPER_NAME2) + .build()) + .build()) + .build(); + + client.apply(addHttpAuthenticationFactory); + + assertTrue("Http authentication factory should be created", ops.exists(TEST_AUTHENTICATION_FACTORY_ADDRESS)); + + checkAttribute("security-domain", TEST_SECURITY_DOMAIN_NAME); + checkAttribute("http-server-mechanism-factory", TEST_SERVER_MECHANISM_FACTORY_NAME); + + checkAttribute("mechanism-configurations[0].mechanism-name", "someMechanismName"); + checkAttribute("mechanism-configurations[0].host-name", "someHostName"); + checkAttribute("mechanism-configurations[0].protocol", "someProtocol"); + checkAttribute("mechanism-configurations[0].pre-realm-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME); + checkAttribute("mechanism-configurations[0].post-realm-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2); + checkAttribute("mechanism-configurations[0].final-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME); + checkAttribute("mechanism-configurations[0].realm-mapper", TEST_SIMPLE_REGEX_REALM_MAPPER_NAME); + checkAttribute("mechanism-configurations[0].credential-security-factory", TEST_KERBEROS_SECURITY_FACTORY_NAME); + + checkAttribute("mechanism-configurations[0].mechanism-realm-configurations[0].realm-name", + TEST_FILESYSTEM_REALM_NAME); + checkAttribute("mechanism-configurations[0].mechanism-realm-configurations[0].pre-realm-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME); + checkAttribute("mechanism-configurations[0].mechanism-realm-configurations[0].post-realm-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2); + checkAttribute("mechanism-configurations[0].mechanism-realm-configurations[0].final-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME); + checkAttribute("mechanism-configurations[0].mechanism-realm-configurations[0].realm-mapper", + TEST_SIMPLE_REGEX_REALM_MAPPER_NAME); + + checkAttribute("mechanism-configurations[0].mechanism-realm-configurations[1].realm-name", + TEST_FILESYSTEM_REALM_NAME2); + checkAttribute("mechanism-configurations[0].mechanism-realm-configurations[1].pre-realm-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2); + checkAttribute("mechanism-configurations[0].mechanism-realm-configurations[1].post-realm-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME); + checkAttribute("mechanism-configurations[0].mechanism-realm-configurations[1].final-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2); + checkAttribute("mechanism-configurations[0].mechanism-realm-configurations[1].realm-mapper", + TEST_SIMPLE_REGEX_REALM_MAPPER_NAME2); + + checkAttribute("mechanism-configurations[1].mechanism-name", "someMechanismName2"); + checkAttribute("mechanism-configurations[1].host-name", "someHostName2"); + checkAttribute("mechanism-configurations[1].protocol", "someProtocol2"); + checkAttribute("mechanism-configurations[1].pre-realm-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2); + checkAttribute("mechanism-configurations[1].post-realm-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME); + checkAttribute("mechanism-configurations[1].final-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2); + checkAttribute("mechanism-configurations[1].realm-mapper", TEST_SIMPLE_REGEX_REALM_MAPPER_NAME2); + checkAttribute("mechanism-configurations[1].credential-security-factory", + TEST_KERBEROS_SECURITY_FACTORY_NAME2); + + checkAttribute("mechanism-configurations[1].mechanism-realm-configurations[0].realm-name", + TEST_FILESYSTEM_REALM_NAME2); + checkAttribute("mechanism-configurations[1].mechanism-realm-configurations[0].pre-realm-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2); + checkAttribute("mechanism-configurations[1].mechanism-realm-configurations[0].post-realm-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2); + checkAttribute("mechanism-configurations[1].mechanism-realm-configurations[0].final-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2); + checkAttribute("mechanism-configurations[1].mechanism-realm-configurations[0].realm-mapper", + TEST_SIMPLE_REGEX_REALM_MAPPER_NAME2); + + } + + @Test(expected = CommandFailedException.class) + public void addExistHttpAuthenticationFactoryNotAllowed() throws Exception { + client.apply(addFilesystemRealm); + client.apply(addSecurityDomain); + client.apply(addProviderHttpServerMechanismFactory); + client.apply(addProviderHttpServerMechanismFactory2); + + AddHttpAuthenticationFactory addHttpAuthenticationFactory + = new AddHttpAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .httpServerMechanismFactory(TEST_SERVER_MECHANISM_FACTORY_NAME) + .build(); + + AddHttpAuthenticationFactory addHttpAuthenticationFactory2 + = new AddHttpAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .httpServerMechanismFactory(TEST_SERVER_MECHANISM_FACTORY_NAME2) + .build(); + + client.apply(addHttpAuthenticationFactory); + assertTrue("Http authentication factory should be created", ops.exists(TEST_AUTHENTICATION_FACTORY_ADDRESS)); + client.apply(addHttpAuthenticationFactory2); + fail("Http authentication factory CreaperTestHttpAuthenticationFactory already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistHttpAuthenticationFactoryAllowed() throws Exception { + client.apply(addFilesystemRealm); + client.apply(addSecurityDomain); + client.apply(addProviderHttpServerMechanismFactory); + client.apply(addProviderHttpServerMechanismFactory2); + + AddHttpAuthenticationFactory addHttpAuthenticationFactory + = new AddHttpAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .httpServerMechanismFactory(TEST_SERVER_MECHANISM_FACTORY_NAME) + .build(); + + AddHttpAuthenticationFactory addHttpAuthenticationFactory2 + = new AddHttpAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .httpServerMechanismFactory(TEST_SERVER_MECHANISM_FACTORY_NAME2) + .replaceExisting() + .build(); + + client.apply(addHttpAuthenticationFactory); + assertTrue("Http authentication factory should be created", ops.exists(TEST_AUTHENTICATION_FACTORY_ADDRESS)); + client.apply(addHttpAuthenticationFactory2); + assertTrue("Http authentication factory should be created", ops.exists(TEST_AUTHENTICATION_FACTORY_ADDRESS)); + // check whether it was really rewritten + checkAttribute("http-server-mechanism-factory", TEST_SERVER_MECHANISM_FACTORY_NAME2); + } + + @Test(expected = IllegalArgumentException.class) + public void addHttpAuthenticationFactory_nullName() throws Exception { + new AddHttpAuthenticationFactory.Builder(null) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .httpServerMechanismFactory(TEST_SERVER_MECHANISM_FACTORY_NAME) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addHttpAuthenticationFactory_emptyName() throws Exception { + new AddHttpAuthenticationFactory.Builder("") + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .httpServerMechanismFactory(TEST_SERVER_MECHANISM_FACTORY_NAME) + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addHttpAuthenticationFactory_nullSecurityDomain() throws Exception { + new AddHttpAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain(null) + .httpServerMechanismFactory(TEST_SERVER_MECHANISM_FACTORY_NAME) + .build(); + fail("Creating command with null security domain should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addHttpAuthenticationFactory_emptySecurityDomain() throws Exception { + new AddHttpAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain("") + .httpServerMechanismFactory(TEST_SERVER_MECHANISM_FACTORY_NAME) + .build(); + fail("Creating command with empty security domain should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addHttpAuthenticationFactory_nullHttpServerMechanismFactory() throws Exception { + new AddHttpAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .httpServerMechanismFactory(null) + .build(); + fail("Creating command with null http server mechanism factory should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addHttpAuthenticationFactory_emptyHttpServerMechanismFactory() throws Exception { + new AddHttpAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .httpServerMechanismFactory("") + .build(); + fail("Creating command with empty http server mechanism factory should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addHttpAuthenticationFactory_nullMechanismConfigurations() throws Exception { + new AddHttpAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .httpServerMechanismFactory(TEST_SERVER_MECHANISM_FACTORY_NAME) + .addMechanismConfigurations(null) + .build(); + fail("Creating command with null mechanism configuration should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addHttpAuthenticationFactory_nullMechanismRealmConfigurations() throws Exception { + new AddHttpAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .httpServerMechanismFactory(TEST_SERVER_MECHANISM_FACTORY_NAME) + .addMechanismConfigurations(new Mechanism.Builder() + .addMechanismRealmConfigurations(null) + .build()) + .build(); + fail("Creating command with null mechanism realm configuration should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addHttpAuthenticationFactory_nullRealmName_mechanismRealm() throws Exception { + new AddHttpAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .httpServerMechanismFactory(TEST_SERVER_MECHANISM_FACTORY_NAME) + .addMechanismConfigurations(new Mechanism.Builder() + .addMechanismRealmConfigurations(new Mechanism.MechanismRealmBuilder() + .realmName(null) + .build()) + .build()) + .build(); + fail("Creating command with null realm name in mechanism realm should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addHttpAuthenticationFactory_emptyRealmName_mechanismRealm() throws Exception { + new AddHttpAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .httpServerMechanismFactory(TEST_SERVER_MECHANISM_FACTORY_NAME) + .addMechanismConfigurations(new Mechanism.Builder() + .addMechanismRealmConfigurations(new Mechanism.MechanismRealmBuilder() + .realmName("") + .build()) + .build()) + .build(); + fail("Creating command with empty realm name in mechanism realm should throw exception"); + } + + private void checkAttribute(String attribute, String expectedValue) throws IOException { + checkAttribute(TEST_AUTHENTICATION_FACTORY_ADDRESS, attribute, expectedValue); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/http/AddProviderHttpServerMechanismFactoryOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/http/AddProviderHttpServerMechanismFactoryOnlineTest.java new file mode 100644 index 00000000..1f6d5f7a --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/http/AddProviderHttpServerMechanismFactoryOnlineTest.java @@ -0,0 +1,138 @@ +package org.wildfly.extras.creaper.commands.elytron.http; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddProviderHttpServerMechanismFactoryOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_SERVER_MECHANISM_FACTORY_NAME + = "CreaperTestProviderHttpServerMechanismFactory"; + private static final Address TEST_SERVER_MECHANISM_FACTORY_ADDRESS = SUBSYSTEM_ADDRESS + .and("provider-http-server-mechanism-factory", TEST_SERVER_MECHANISM_FACTORY_NAME); + private static final String TEST_SERVER_MECHANISM_FACTORY_NAME2 + = "CreaperTestProviderHttpServerMechanismFactory2"; + private static final Address TEST_SERVER_MECHANISM_FACTORY_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("provider-http-server-mechanism-factory", TEST_SERVER_MECHANISM_FACTORY_NAME2); + + private static final String PROVIDER_LOADER_NAME = "elytron"; + private static final String PROVIDER_LOADER_NAME2 = "combined-providers"; + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS); + ops.removeIfExists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleProviderHttpServerMechanismFactory() throws Exception { + AddProviderHttpServerMechanismFactory addProviderHttpServerMechanismFactory + = new AddProviderHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .build(); + + client.apply(addProviderHttpServerMechanismFactory); + + assertTrue("Provider http server mechanism factory should be created", + ops.exists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS)); + } + + @Test + public void addTwoProviderHttpServerMechanismFactories() throws Exception { + AddProviderHttpServerMechanismFactory addProviderHttpServerMechanismFactory + = new AddProviderHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .build(); + + AddProviderHttpServerMechanismFactory addProviderHttpServerMechanismFactory2 + = new AddProviderHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME2) + .build(); + + client.apply(addProviderHttpServerMechanismFactory); + client.apply(addProviderHttpServerMechanismFactory2); + + assertTrue("Provider http server mechanism factory should be created", + ops.exists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS)); + assertTrue("Second provider http server mechanism factory should be created", + ops.exists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS2)); + } + + @Test + public void addFullProviderHttpServerMechanismFactory() throws Exception { + AddProviderHttpServerMechanismFactory addProviderHttpServerMechanismFactory + = new AddProviderHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .providers(PROVIDER_LOADER_NAME) + .build(); + + client.apply(addProviderHttpServerMechanismFactory); + + assertTrue("Provider http server mechanism factory should be created", + ops.exists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS)); + + checkAttribute(TEST_SERVER_MECHANISM_FACTORY_ADDRESS, "providers", PROVIDER_LOADER_NAME); + + } + + @Test(expected = CommandFailedException.class) + public void addExistProviderHttpServerMechanismFactoryNotAllowed() throws Exception { + AddProviderHttpServerMechanismFactory addProviderHttpServerMechanismFactory + = new AddProviderHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .providers(PROVIDER_LOADER_NAME) + .build(); + + AddProviderHttpServerMechanismFactory addProviderHttpServerMechanismFactory2 + = new AddProviderHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .providers(PROVIDER_LOADER_NAME2) + .build(); + + client.apply(addProviderHttpServerMechanismFactory); + assertTrue("Provider http server mechanism factory should be created", + ops.exists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS)); + client.apply(addProviderHttpServerMechanismFactory2); + fail("Provider http server mechanism factory CreaperTestProviderHttpServerMechanismFactory already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistProviderHttpServerMechanismFactoryAllowed() throws Exception { + AddProviderHttpServerMechanismFactory addProviderHttpServerMechanismFactory + = new AddProviderHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .providers(PROVIDER_LOADER_NAME) + .build(); + + AddProviderHttpServerMechanismFactory addProviderHttpServerMechanismFactory2 + = new AddProviderHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .providers(PROVIDER_LOADER_NAME2) + .replaceExisting() + .build(); + + client.apply(addProviderHttpServerMechanismFactory); + assertTrue("Provider http server mechanism factory should be created", + ops.exists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS)); + client.apply(addProviderHttpServerMechanismFactory2); + assertTrue("Provider http server mechanism factory should be created", + ops.exists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS)); + // check whether it was really rewritten + checkAttribute(TEST_SERVER_MECHANISM_FACTORY_ADDRESS, "providers", PROVIDER_LOADER_NAME2); + } + + @Test(expected = IllegalArgumentException.class) + public void addProviderHttpServerMechanismFactory_nullName() throws Exception { + new AddProviderHttpServerMechanismFactory.Builder(null) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addProviderHttpServerMechanismFactory_emptyName() throws Exception { + new AddProviderHttpServerMechanismFactory.Builder("") + .build(); + fail("Creating command with empty name should throw exception"); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/http/AddServiceLoaderHttpServerMechanismFactoryOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/http/AddServiceLoaderHttpServerMechanismFactoryOnlineTest.java new file mode 100644 index 00000000..fcecacd2 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/http/AddServiceLoaderHttpServerMechanismFactoryOnlineTest.java @@ -0,0 +1,139 @@ +package org.wildfly.extras.creaper.commands.elytron.http; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddServiceLoaderHttpServerMechanismFactoryOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_SERVER_MECHANISM_FACTORY_NAME + = "CreaperTestServiceLoaderHttpServerMechanismFactory"; + private static final Address TEST_SERVER_MECHANISM_FACTORY_ADDRESS = SUBSYSTEM_ADDRESS + .and("service-loader-http-server-mechanism-factory", TEST_SERVER_MECHANISM_FACTORY_NAME); + private static final String TEST_SERVER_MECHANISM_FACTORY_NAME2 + = "CreaperTestServiceLoaderHttpServerMechanismFactory2"; + private static final Address TEST_SERVER_MECHANISM_FACTORY_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("service-loader-http-server-mechanism-factory", TEST_SERVER_MECHANISM_FACTORY_NAME2); + + private static final String ELYTRON_MODULE = "org.wildfly.security.elytron"; + private static final String ELYTRON_SUBSYTEM_MODULE = "org.wildfly.extension.elytron"; + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS); + ops.removeIfExists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleServiceLoaderHttpServerMechanismFactory() throws Exception { + AddServiceLoaderHttpServerMechanismFactory addServiceLoaderHttpServerMechanismFactory + = new AddServiceLoaderHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .build(); + + client.apply(addServiceLoaderHttpServerMechanismFactory); + + assertTrue("Service loader http server mechanism factory should be created", + ops.exists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS)); + + } + + @Test + public void addTwoServiceLoaderHttpServerMechanismFactories() throws Exception { + AddServiceLoaderHttpServerMechanismFactory addServiceLoaderHttpServerMechanismFactory + = new AddServiceLoaderHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .build(); + + AddServiceLoaderHttpServerMechanismFactory addServiceLoaderHttpServerMechanismFactory2 + = new AddServiceLoaderHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME2) + .build(); + + client.apply(addServiceLoaderHttpServerMechanismFactory); + client.apply(addServiceLoaderHttpServerMechanismFactory2); + + assertTrue("Service loader http server mechanism factory should be created", + ops.exists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS)); + assertTrue("Second service loader http server mechanism factory should be created", + ops.exists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS2)); + } + + @Test + public void addFullServiceLoaderHttpServerMechanismFactory() throws Exception { + AddServiceLoaderHttpServerMechanismFactory addServiceLoaderHttpServerMechanismFactory + = new AddServiceLoaderHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .module(ELYTRON_MODULE) + .build(); + + client.apply(addServiceLoaderHttpServerMechanismFactory); + + assertTrue("Service loader http server mechanism factory should be created", + ops.exists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS)); + + checkAttribute(TEST_SERVER_MECHANISM_FACTORY_ADDRESS, "module", ELYTRON_MODULE); + + } + + @Test(expected = CommandFailedException.class) + public void addExistServiceLoaderHttpServerMechanismFactoryNotAllowed() throws Exception { + AddServiceLoaderHttpServerMechanismFactory addServiceLoaderHttpServerMechanismFactory + = new AddServiceLoaderHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .module(ELYTRON_MODULE) + .build(); + + AddServiceLoaderHttpServerMechanismFactory addServiceLoaderHttpServerMechanismFactory2 + = new AddServiceLoaderHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .module(ELYTRON_SUBSYTEM_MODULE) + .build(); + + client.apply(addServiceLoaderHttpServerMechanismFactory); + assertTrue("Service loader http server mechanism factory should be created", + ops.exists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS)); + client.apply(addServiceLoaderHttpServerMechanismFactory2); + fail("Service loader http server mechanism factory CreaperTestServiceLoaderHttpServerMechanismFactory already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistServiceLoaderHttpServerMechanismFactoryAllowed() throws Exception { + AddServiceLoaderHttpServerMechanismFactory addServiceLoaderHttpServerMechanismFactory + = new AddServiceLoaderHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .module(ELYTRON_MODULE) + .build(); + + AddServiceLoaderHttpServerMechanismFactory addServiceLoaderHttpServerMechanismFactory2 + = new AddServiceLoaderHttpServerMechanismFactory.Builder(TEST_SERVER_MECHANISM_FACTORY_NAME) + .module(ELYTRON_SUBSYTEM_MODULE) + .replaceExisting() + .build(); + + client.apply(addServiceLoaderHttpServerMechanismFactory); + assertTrue("Service loader http server mechanism factory should be created", + ops.exists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS)); + client.apply(addServiceLoaderHttpServerMechanismFactory2); + assertTrue("Service loader http server mechanism factory should be created", + ops.exists(TEST_SERVER_MECHANISM_FACTORY_ADDRESS)); + // check whether it was really rewritten + checkAttribute(TEST_SERVER_MECHANISM_FACTORY_ADDRESS, "module", ELYTRON_SUBSYTEM_MODULE); + } + + @Test(expected = IllegalArgumentException.class) + public void addServiceLoaderHttpServerMechanismFactory_nullName() throws Exception { + new AddServiceLoaderHttpServerMechanismFactory.Builder(null) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addServiceLoaderHttpServerMechanismFactory_emptyName() throws Exception { + new AddServiceLoaderHttpServerMechanismFactory.Builder("") + .build(); + fail("Creating command with empty name should throw exception"); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AbstractAddPrincipalDecoderOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AbstractAddPrincipalDecoderOnlineTest.java new file mode 100644 index 00000000..91687da7 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AbstractAddPrincipalDecoderOnlineTest.java @@ -0,0 +1,74 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import java.util.Arrays; +import java.util.List; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.online.OnlineManagementClient; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public class AbstractAddPrincipalDecoderOnlineTest extends AbstractElytronOnlineTest { + + protected static final String TEST_CONSTANT_PRINCIPAL_DECODER_NAME = "CreaperTestConstantPrincipalDecoder"; + protected static final Address TEST_CONSTANT_PRINCIPAL_DECODER_ADDRESS = SUBSYSTEM_ADDRESS + .and("constant-principal-decoder", TEST_CONSTANT_PRINCIPAL_DECODER_NAME); + protected static final String TEST_CONSTANT_PRINCIPAL_DECODER_NAME2 = "CreaperTestConstantPrincipalDecoder2"; + protected static final Address TEST_CONSTANT_PRINCIPAL_DECODER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("constant-principal-decoder", TEST_CONSTANT_PRINCIPAL_DECODER_NAME2); + protected static final String TEST_DIFFERENT_PRINCIPAL_DECODER_NAME = "CreaperTestConstantPrincipalDecoder3"; + protected static final Address TEST_DIFFERENT_PRINCIPAL_DECODER_ADDRESS = SUBSYSTEM_ADDRESS + .and("constant-principal-decoder", TEST_DIFFERENT_PRINCIPAL_DECODER_NAME); + + protected static final List PRINCIPAL_DECODERS_1_AND_2 + = Arrays.asList(TEST_CONSTANT_PRINCIPAL_DECODER_NAME, TEST_CONSTANT_PRINCIPAL_DECODER_NAME2); + protected static final List PRINCIPAL_DECODERS_2_AND_DIFFERENT + = Arrays.asList(TEST_CONSTANT_PRINCIPAL_DECODER_NAME2, TEST_DIFFERENT_PRINCIPAL_DECODER_NAME); + + @BeforeClass + public static void addPrincipalDecoders() throws Exception { + OnlineManagementClient client = null; + try { + client = createManagementClient(); + AddConstantPrincipalDecoder addConstantPrincipalDecoder + = new AddConstantPrincipalDecoder.Builder(TEST_CONSTANT_PRINCIPAL_DECODER_NAME) + .constant("role1") + .build(); + AddConstantPrincipalDecoder addConstantPrincipalDecoder2 + = new AddConstantPrincipalDecoder.Builder(TEST_CONSTANT_PRINCIPAL_DECODER_NAME2) + .constant("role2") + .build(); + AddConstantPrincipalDecoder addConstantPrincipalDecoder3 + = new AddConstantPrincipalDecoder.Builder(TEST_DIFFERENT_PRINCIPAL_DECODER_NAME) + .constant("role3") + .build(); + client.apply(addConstantPrincipalDecoder); + client.apply(addConstantPrincipalDecoder2); + client.apply(addConstantPrincipalDecoder3); + } finally { + if (client != null) { + client.close(); + } + } + } + + @AfterClass + public static void removePrincipalDecoders() throws Exception { + OnlineManagementClient client = null; + try { + client = createManagementClient(); + Operations ops = new Operations(client); + ops.removeIfExists(TEST_CONSTANT_PRINCIPAL_DECODER_ADDRESS); + ops.removeIfExists(TEST_CONSTANT_PRINCIPAL_DECODER_ADDRESS2); + ops.removeIfExists(TEST_DIFFERENT_PRINCIPAL_DECODER_ADDRESS); + new Administration(client).reloadIfRequired(); + } finally { + if (client != null) { + client.close(); + } + } + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AbstractAddPrincipalTransformerOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AbstractAddPrincipalTransformerOnlineTest.java new file mode 100644 index 00000000..a6d71edb --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AbstractAddPrincipalTransformerOnlineTest.java @@ -0,0 +1,74 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import java.util.Arrays; +import java.util.List; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.online.OnlineManagementClient; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public class AbstractAddPrincipalTransformerOnlineTest extends AbstractElytronOnlineTest { + + protected static final String TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME = "CreaperTestConstantPrincipalTransformer"; + protected static final Address TEST_CONSTANT_PRINCIPAL_TRANSFORMER_ADDRESS = SUBSYSTEM_ADDRESS + .and("constant-principal-transformer", TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME); + protected static final String TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2 = "CreaperTestConstantPrincipalTransformer2"; + protected static final Address TEST_CONSTANT_PRINCIPAL_TRANSFORMER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("constant-principal-transformer", TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2); + protected static final String TEST_DIFFERENT_PRINCIPAL_TRANSFORMER_NAME = "CreaperTestConstantPrincipalTransformer3"; + protected static final Address TEST_DIFFERENT_PRINCIPAL_TRANSFORMER_ADDRESS = SUBSYSTEM_ADDRESS + .and("constant-principal-transformer", TEST_DIFFERENT_PRINCIPAL_TRANSFORMER_NAME); + + protected static final List PRINCIPAL_TRANSFORMERS_1_AND_2 + = Arrays.asList(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME, TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2); + protected static final List PRINCIPAL_TRANSFORMERS_2_AND_DIFFERENT + = Arrays.asList(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2, TEST_DIFFERENT_PRINCIPAL_TRANSFORMER_NAME); + + @BeforeClass + public static void addPrincipalTransformers() throws Exception { + OnlineManagementClient client = null; + try { + client = createManagementClient(); + AddConstantPrincipalTransformer addConstantPrincipalTransformer + = new AddConstantPrincipalTransformer.Builder(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME) + .constant("name1") + .build(); + AddConstantPrincipalTransformer addConstantPrincipalTransformer2 + = new AddConstantPrincipalTransformer.Builder(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .constant("name2") + .build(); + AddConstantPrincipalTransformer addConstantPrincipalTransformer3 + = new AddConstantPrincipalTransformer.Builder(TEST_DIFFERENT_PRINCIPAL_TRANSFORMER_NAME) + .constant("name3") + .build(); + client.apply(addConstantPrincipalTransformer); + client.apply(addConstantPrincipalTransformer2); + client.apply(addConstantPrincipalTransformer3); + } finally { + if (client != null) { + client.close(); + } + } + } + + @AfterClass + public static void removePrincipalTransformers() throws Exception { + OnlineManagementClient client = null; + try { + client = createManagementClient(); + Operations ops = new Operations(client); + ops.removeIfExists(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_ADDRESS); + ops.removeIfExists(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_ADDRESS2); + ops.removeIfExists(TEST_DIFFERENT_PRINCIPAL_TRANSFORMER_ADDRESS); + Administration administration = new Administration(client); + administration.reloadIfRequired(); + } finally { + if (client != null) { + client.close(); + } + } + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAddPrefixRoleMapperOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAddPrefixRoleMapperOnlineTest.java new file mode 100644 index 00000000..cc9595d6 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAddPrefixRoleMapperOnlineTest.java @@ -0,0 +1,103 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddAddPrefixRoleMapperOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_ADD_PREFIX_ROLE_MAPPER_NAME = "CreaperTestAddPrefixRoleMapper"; + private static final Address TEST_ADD_PREFIX_ROLE_MAPPER_ADDRESS = SUBSYSTEM_ADDRESS + .and("add-prefix-role-mapper", TEST_ADD_PREFIX_ROLE_MAPPER_NAME); + private static final String TEST_ADD_PREFIX_ROLE_MAPPER_NAME2 = "CreaperTestAddPrefixRoleMapper2"; + private static final Address TEST_ADD_PREFIX_ROLE_MAPPER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("add-prefix-role-mapper", TEST_ADD_PREFIX_ROLE_MAPPER_NAME2); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_ADD_PREFIX_ROLE_MAPPER_ADDRESS); + ops.removeIfExists(TEST_ADD_PREFIX_ROLE_MAPPER_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addAddPrefixRoleMapper() throws Exception { + AddAddPrefixRoleMapper addAddPrefixRoleMapper = + new AddAddPrefixRoleMapper.Builder(TEST_ADD_PREFIX_ROLE_MAPPER_NAME) + .prefix("somePrefix").build(); + + client.apply(addAddPrefixRoleMapper); + + assertTrue("Add prefix role mapper should be created", ops.exists(TEST_ADD_PREFIX_ROLE_MAPPER_ADDRESS)); + } + + @Test + public void addAddPrefixRoleMappers() throws Exception { + AddAddPrefixRoleMapper addAddPrefixRoleMapper = + new AddAddPrefixRoleMapper.Builder(TEST_ADD_PREFIX_ROLE_MAPPER_NAME) + .prefix("somePrefix1").build(); + + AddAddPrefixRoleMapper addAddPrefixRoleMapper2 = + new AddAddPrefixRoleMapper.Builder(TEST_ADD_PREFIX_ROLE_MAPPER_NAME2) + .prefix("somePrefix2").build(); + + client.apply(addAddPrefixRoleMapper); + client.apply(addAddPrefixRoleMapper2); + + assertTrue("Add prefix role mapper should be created", ops.exists(TEST_ADD_PREFIX_ROLE_MAPPER_ADDRESS)); + assertTrue("Second add prefix role mapper should be created", ops.exists(TEST_ADD_PREFIX_ROLE_MAPPER_ADDRESS2)); + + checkAttribute(TEST_ADD_PREFIX_ROLE_MAPPER_ADDRESS, "prefix", "somePrefix1"); + checkAttribute(TEST_ADD_PREFIX_ROLE_MAPPER_ADDRESS2, "prefix", "somePrefix2"); + + administration.reload(); + + checkAttribute(TEST_ADD_PREFIX_ROLE_MAPPER_ADDRESS, "prefix", "somePrefix1"); + checkAttribute(TEST_ADD_PREFIX_ROLE_MAPPER_ADDRESS2, "prefix", "somePrefix2"); + } + + @Test(expected = CommandFailedException.class) + public void addDuplicateAddPrefixRoleMapperNotAllowed() throws Exception { + AddAddPrefixRoleMapper addAddPrefixRoleMapper = + new AddAddPrefixRoleMapper.Builder(TEST_ADD_PREFIX_ROLE_MAPPER_NAME) + .prefix("somePrefix").build(); + + client.apply(addAddPrefixRoleMapper); + assertTrue("Add prefix role mapper should be created", ops.exists(TEST_ADD_PREFIX_ROLE_MAPPER_ADDRESS)); + client.apply(addAddPrefixRoleMapper); + fail("Add prefix role mapper " + TEST_ADD_PREFIX_ROLE_MAPPER_NAME + + " already exists in configuration, exception should be thrown"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAddPrefixRoleMapper_nullName() throws Exception { + new AddAddPrefixRoleMapper.Builder(null); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAddPrefixRoleMapper_emptyName() throws Exception { + new AddAddPrefixRoleMapper.Builder(""); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAddPrefixRoleMapper_noPrefix() throws Exception { + new AddAddPrefixRoleMapper.Builder(TEST_ADD_PREFIX_ROLE_MAPPER_NAME).build(); + fail("Creating command with no prefix should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAddPrefixRoleMapper_emptyPrefix() throws Exception { + new AddAddPrefixRoleMapper.Builder(TEST_ADD_PREFIX_ROLE_MAPPER_NAME).prefix("").build(); + fail("Creating command with empty prefix should throw exception"); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAddSuffixRoleMapperOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAddSuffixRoleMapperOnlineTest.java new file mode 100644 index 00000000..2546573b --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAddSuffixRoleMapperOnlineTest.java @@ -0,0 +1,103 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddAddSuffixRoleMapperOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_ADD_SUFFIX_ROLE_MAPPER_NAME = "CreaperTestAddSuffixRoleMapper"; + private static final Address TEST_ADD_SUFFIX_ROLE_MAPPER_ADDRESS = SUBSYSTEM_ADDRESS + .and("add-suffix-role-mapper", TEST_ADD_SUFFIX_ROLE_MAPPER_NAME); + private static final String TEST_ADD_SUFFIX_ROLE_MAPPER_NAME2 = "CreaperTestAddSuffixRoleMapper2"; + private static final Address TEST_ADD_SUFFIX_ROLE_MAPPER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("add-suffix-role-mapper", TEST_ADD_SUFFIX_ROLE_MAPPER_NAME2); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_ADD_SUFFIX_ROLE_MAPPER_ADDRESS); + ops.removeIfExists(TEST_ADD_SUFFIX_ROLE_MAPPER_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addAddSuffixRoleMapper() throws Exception { + AddAddSuffixRoleMapper addAddSuffixRoleMapper = + new AddAddSuffixRoleMapper.Builder(TEST_ADD_SUFFIX_ROLE_MAPPER_NAME) + .suffix("someSuffix").build(); + + client.apply(addAddSuffixRoleMapper); + + assertTrue("Add suffix role mapper should be created", ops.exists(TEST_ADD_SUFFIX_ROLE_MAPPER_ADDRESS)); + } + + @Test + public void addAddSuffixRoleMappers() throws Exception { + AddAddSuffixRoleMapper addAddSuffixRoleMapper = + new AddAddSuffixRoleMapper.Builder(TEST_ADD_SUFFIX_ROLE_MAPPER_NAME) + .suffix("someSuffix1").build(); + + AddAddSuffixRoleMapper addAddSuffixRoleMapper2 = + new AddAddSuffixRoleMapper.Builder(TEST_ADD_SUFFIX_ROLE_MAPPER_NAME2) + .suffix("someSuffix2").build(); + + client.apply(addAddSuffixRoleMapper); + client.apply(addAddSuffixRoleMapper2); + + assertTrue("Add suffix role mapper should be created", ops.exists(TEST_ADD_SUFFIX_ROLE_MAPPER_ADDRESS)); + assertTrue("Second add suffix role mapper should be created", ops.exists(TEST_ADD_SUFFIX_ROLE_MAPPER_ADDRESS2)); + + checkAttribute(TEST_ADD_SUFFIX_ROLE_MAPPER_ADDRESS, "suffix", "someSuffix1"); + checkAttribute(TEST_ADD_SUFFIX_ROLE_MAPPER_ADDRESS2, "suffix", "someSuffix2"); + + administration.reload(); + + checkAttribute(TEST_ADD_SUFFIX_ROLE_MAPPER_ADDRESS, "suffix", "someSuffix1"); + checkAttribute(TEST_ADD_SUFFIX_ROLE_MAPPER_ADDRESS2, "suffix", "someSuffix2"); + } + + @Test(expected = CommandFailedException.class) + public void addDuplicateAddSuffixRoleMapperNotAllowed() throws Exception { + AddAddSuffixRoleMapper addAddSuffixRoleMapper = + new AddAddSuffixRoleMapper.Builder(TEST_ADD_SUFFIX_ROLE_MAPPER_NAME) + .suffix("someSuffix").build(); + + client.apply(addAddSuffixRoleMapper); + assertTrue("Add suffix role mapper should be created", ops.exists(TEST_ADD_SUFFIX_ROLE_MAPPER_ADDRESS)); + client.apply(addAddSuffixRoleMapper); + fail("Add suffix role mapper " + TEST_ADD_SUFFIX_ROLE_MAPPER_NAME + + " already exists in configuration, exception should be thrown"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAddSuffixRoleMapper_nullName() throws Exception { + new AddAddSuffixRoleMapper.Builder(null); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAddSuffixRoleMapper_emptyName() throws Exception { + new AddAddSuffixRoleMapper.Builder(""); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAddSuffixRoleMapper_noSuffix() throws Exception { + new AddAddSuffixRoleMapper.Builder(TEST_ADD_SUFFIX_ROLE_MAPPER_NAME).build(); + fail("Creating command with no suffix should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAddSuffixRoleMapper_emptySuffix() throws Exception { + new AddAddSuffixRoleMapper.Builder(TEST_ADD_SUFFIX_ROLE_MAPPER_NAME).suffix("").build(); + fail("Creating command with empty suffix should throw exception"); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAggregatePrincipalDecoderOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAggregatePrincipalDecoderOnlineTest.java new file mode 100644 index 00000000..04b63ec6 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAggregatePrincipalDecoderOnlineTest.java @@ -0,0 +1,165 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import java.io.IOException; +import java.util.List; +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +@RunWith(Arquillian.class) +public class AddAggregatePrincipalDecoderOnlineTest extends AbstractAddPrincipalDecoderOnlineTest { + + private static final String TEST_AGGREGATE_PRINCIPAL_DECODER_NAME = "CreaperTestAggregatePrincipalDecoder"; + private static final Address TEST_AGGREGATE_PRINCIPAL_DECODER_ADDRESS = SUBSYSTEM_ADDRESS + .and("aggregate-principal-decoder", TEST_AGGREGATE_PRINCIPAL_DECODER_NAME); + private static final String TEST_AGGREGATE_PRINCIPAL_DECODER_NAME2 = "CreaperTestAggregatePrincipalDecoder2"; + private static final Address TEST_AGGREGATE_PRINCIPAL_DECODER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("aggregate-principal-decoder", TEST_AGGREGATE_PRINCIPAL_DECODER_NAME2); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_AGGREGATE_PRINCIPAL_DECODER_ADDRESS); + ops.removeIfExists(TEST_AGGREGATE_PRINCIPAL_DECODER_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addAggregatePrincipalDecoder() throws Exception { + AddAggregatePrincipalDecoder addAggregatePricipalDecoder + = new AddAggregatePrincipalDecoder.Builder(TEST_AGGREGATE_PRINCIPAL_DECODER_NAME) + .principalDecoders(TEST_CONSTANT_PRINCIPAL_DECODER_NAME, TEST_CONSTANT_PRINCIPAL_DECODER_NAME2) + .build(); + + client.apply(addAggregatePricipalDecoder); + + assertTrue("Aggregate-principal-decoder should be created", + ops.exists(TEST_AGGREGATE_PRINCIPAL_DECODER_ADDRESS)); + checkAggregatePrincipalDecoderAttribute("principal-decoders", PRINCIPAL_DECODERS_1_AND_2); + } + + @Test + public void addTwoAggregatePrincipalDecoders() throws Exception { + AddAggregatePrincipalDecoder addAggregatePricipalDecoder + = new AddAggregatePrincipalDecoder.Builder(TEST_AGGREGATE_PRINCIPAL_DECODER_NAME) + .principalDecoders(TEST_CONSTANT_PRINCIPAL_DECODER_NAME, TEST_CONSTANT_PRINCIPAL_DECODER_NAME2) + .build(); + + AddAggregatePrincipalDecoder addAggregatePricipalDecoder2 + = new AddAggregatePrincipalDecoder.Builder(TEST_AGGREGATE_PRINCIPAL_DECODER_NAME2) + .principalDecoders(TEST_CONSTANT_PRINCIPAL_DECODER_NAME2, TEST_DIFFERENT_PRINCIPAL_DECODER_NAME) + .build(); + + client.apply(addAggregatePricipalDecoder); + client.apply(addAggregatePricipalDecoder2); + + assertTrue("Aggregate-principal-decoder should be created", + ops.exists(TEST_AGGREGATE_PRINCIPAL_DECODER_ADDRESS)); + assertTrue("Aggregate-principal-decoder should be created", + ops.exists(TEST_AGGREGATE_PRINCIPAL_DECODER_ADDRESS2)); + } + + @Test(expected = CommandFailedException.class) + public void addExistAggregatePrincipalDecodersNotAllowed() throws Exception { + AddAggregatePrincipalDecoder addAggregatePricipalDecoder + = new AddAggregatePrincipalDecoder.Builder(TEST_AGGREGATE_PRINCIPAL_DECODER_NAME) + .principalDecoders(TEST_CONSTANT_PRINCIPAL_DECODER_NAME, TEST_CONSTANT_PRINCIPAL_DECODER_NAME2) + .build(); + + AddAggregatePrincipalDecoder addAggregatePricipalDecoder2 + = new AddAggregatePrincipalDecoder.Builder(TEST_AGGREGATE_PRINCIPAL_DECODER_NAME) + .principalDecoders(TEST_CONSTANT_PRINCIPAL_DECODER_NAME2, TEST_DIFFERENT_PRINCIPAL_DECODER_NAME) + .build(); + + client.apply(addAggregatePricipalDecoder); + assertTrue("Aggregate-principal-decoder should be created", + ops.exists(TEST_AGGREGATE_PRINCIPAL_DECODER_ADDRESS)); + + client.apply(addAggregatePricipalDecoder2); + fail("Aggregate-principal-decoder CreaperTestAggregatePrincipalDecoder already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistAggregatePrincipalDecodersAllowed() throws Exception { + AddAggregatePrincipalDecoder addAggregatePricipalDecoder + = new AddAggregatePrincipalDecoder.Builder(TEST_AGGREGATE_PRINCIPAL_DECODER_NAME) + .principalDecoders(TEST_CONSTANT_PRINCIPAL_DECODER_NAME, TEST_CONSTANT_PRINCIPAL_DECODER_NAME2) + .build(); + + AddAggregatePrincipalDecoder addAggregatePricipalDecoder2 + = new AddAggregatePrincipalDecoder.Builder(TEST_AGGREGATE_PRINCIPAL_DECODER_NAME) + .principalDecoders(TEST_CONSTANT_PRINCIPAL_DECODER_NAME2, TEST_DIFFERENT_PRINCIPAL_DECODER_NAME) + .replaceExisting() + .build(); + + client.apply(addAggregatePricipalDecoder); + assertTrue("Aggregate-principal-decoder should be created", + ops.exists(TEST_AGGREGATE_PRINCIPAL_DECODER_ADDRESS)); + + client.apply(addAggregatePricipalDecoder2); + assertTrue("Aggregate-principal-decoder should be created", + ops.exists(TEST_AGGREGATE_PRINCIPAL_DECODER_ADDRESS)); + checkAggregatePrincipalDecoderAttribute("principal-decoders", PRINCIPAL_DECODERS_2_AND_DIFFERENT); + } + + @Test(expected = CommandFailedException.class) + public void addAggregatePrincipalDecoderWithoutConfiguredPrincipalsDecoders() throws Exception { + AddAggregatePrincipalDecoder addAggregatePricipalDecoder + = new AddAggregatePrincipalDecoder.Builder(TEST_AGGREGATE_PRINCIPAL_DECODER_NAME) + .principalDecoders(TEST_CONSTANT_PRINCIPAL_DECODER_NAME, "NotConfiguredPrincipalDecoder") + .build(); + + client.apply(addAggregatePricipalDecoder); + fail("Aggregate-principal-decoder shouldn't be added when using unconfigured principal decoder"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregatePrincipalDecoder_nullName() throws Exception { + new AddAggregatePrincipalDecoder.Builder(null) + .principalDecoders(TEST_CONSTANT_PRINCIPAL_DECODER_NAME, TEST_CONSTANT_PRINCIPAL_DECODER_NAME2) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregatePrincipalDecoder_emptyName() throws Exception { + new AddAggregatePrincipalDecoder.Builder("") + .principalDecoders(TEST_CONSTANT_PRINCIPAL_DECODER_NAME, TEST_CONSTANT_PRINCIPAL_DECODER_NAME2) + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregatePrincipalDecoder_nullPrincipalDecoders() throws Exception { + new AddAggregatePrincipalDecoder.Builder(TEST_AGGREGATE_PRINCIPAL_DECODER_NAME) + .principalDecoders(null) + .build(); + fail("Creating command with null principal-decoders should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregatePrincipalDecoder_emptyPrincipalDecoders() throws Exception { + new AddAggregatePrincipalDecoder.Builder(TEST_AGGREGATE_PRINCIPAL_DECODER_NAME) + .principalDecoders("") + .build(); + fail("Creating command with empty principal-decoders should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregatePrincipalDecoder_onePrincipalDecoder() throws Exception { + new AddAggregatePrincipalDecoder.Builder(TEST_AGGREGATE_PRINCIPAL_DECODER_NAME) + .principalDecoders(TEST_CONSTANT_PRINCIPAL_DECODER_NAME) + .build(); + fail("Creating command with only one principal-decoder should throw exception"); + } + + private void checkAggregatePrincipalDecoderAttribute(String attr, List expected) throws IOException { + checkAttribute(TEST_AGGREGATE_PRINCIPAL_DECODER_ADDRESS, attr, expected); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAggregatePrincipalTransformerOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAggregatePrincipalTransformerOnlineTest.java new file mode 100644 index 00000000..07aafedf --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAggregatePrincipalTransformerOnlineTest.java @@ -0,0 +1,171 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.wildfly.extras.creaper.commands.elytron.mapper.AbstractAddPrincipalTransformerOnlineTest.TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME; + +@RunWith(Arquillian.class) +public class AddAggregatePrincipalTransformerOnlineTest extends AbstractAddPrincipalTransformerOnlineTest { + + private static final String TEST_AGGREGATE_PRINCIPAL_TRANSFORMER_NAME = "CreaperTestAggregatePrincipalTransformer"; + private static final Address TEST_AGGREGATE_PRINCIPAL_TRANSFORMER_ADDRESS = SUBSYSTEM_ADDRESS + .and("aggregate-principal-transformer", TEST_AGGREGATE_PRINCIPAL_TRANSFORMER_NAME); + private static final String TEST_AGGREGATE_PRINCIPAL_TRANSFORMER_NAME2 = "CreaperTestAggregatePrincipalTransformer2"; + private static final Address TEST_AGGREGATE_PRINCIPAL_TRANSFORMER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("aggregate-principal-transformer", TEST_AGGREGATE_PRINCIPAL_TRANSFORMER_NAME2); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_AGGREGATE_PRINCIPAL_TRANSFORMER_ADDRESS); + ops.removeIfExists(TEST_AGGREGATE_PRINCIPAL_TRANSFORMER_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addAggregatePrincipalTransformer() throws Exception { + AddAggregatePrincipalTransformer addAggregatePrincipalTransformer + = new AddAggregatePrincipalTransformer.Builder(TEST_AGGREGATE_PRINCIPAL_TRANSFORMER_NAME) + .principalTransformers(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME, + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .build(); + + client.apply(addAggregatePrincipalTransformer); + + assertTrue("Aggregate-principal-transformer should be created", + ops.exists(TEST_AGGREGATE_PRINCIPAL_TRANSFORMER_ADDRESS)); + checkAttribute(TEST_AGGREGATE_PRINCIPAL_TRANSFORMER_ADDRESS, "principal-transformers", + PRINCIPAL_TRANSFORMERS_1_AND_2); + } + + @Test + public void addTwoAggregatePrincipalTransformers() throws Exception { + AddAggregatePrincipalTransformer addAggregatePrincipalTransformer + = new AddAggregatePrincipalTransformer.Builder(TEST_AGGREGATE_PRINCIPAL_TRANSFORMER_NAME) + .principalTransformers(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME, + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .build(); + + AddAggregatePrincipalTransformer addAggregatePrincipalTransformer2 + = new AddAggregatePrincipalTransformer.Builder(TEST_AGGREGATE_PRINCIPAL_TRANSFORMER_NAME2) + .principalTransformers(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2, + TEST_DIFFERENT_PRINCIPAL_TRANSFORMER_NAME) + .build(); + + client.apply(addAggregatePrincipalTransformer); + client.apply(addAggregatePrincipalTransformer2); + + assertTrue("Aggregate-principal-transformer should be created", + ops.exists(TEST_AGGREGATE_PRINCIPAL_TRANSFORMER_ADDRESS)); + assertTrue("Aggregate-principal-transformer should be created", + ops.exists(TEST_AGGREGATE_PRINCIPAL_TRANSFORMER_ADDRESS2)); + } + + @Test(expected = CommandFailedException.class) + public void addExistAggregatePrincipalTransformersNotAllowed() throws Exception { + AddAggregatePrincipalTransformer addAggregatePrincipalTransformer + = new AddAggregatePrincipalTransformer.Builder(TEST_AGGREGATE_PRINCIPAL_TRANSFORMER_NAME) + .principalTransformers(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME, + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .build(); + + AddAggregatePrincipalTransformer addAggregatePrincipalTransformer2 + = new AddAggregatePrincipalTransformer.Builder(TEST_AGGREGATE_PRINCIPAL_TRANSFORMER_NAME) + .principalTransformers(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2, + TEST_DIFFERENT_PRINCIPAL_TRANSFORMER_NAME) + .build(); + + client.apply(addAggregatePrincipalTransformer); + assertTrue("Aggregate-principal-transformer should be created", + ops.exists(TEST_AGGREGATE_PRINCIPAL_TRANSFORMER_ADDRESS)); + + client.apply(addAggregatePrincipalTransformer2); + fail("Aggregate-principal-transformer CreaperTestAggregatePrincipalTransformer already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistAggregatePrincipalTransformersAllowed() throws Exception { + AddAggregatePrincipalTransformer addAggregatePrincipalTransformer + = new AddAggregatePrincipalTransformer.Builder(TEST_AGGREGATE_PRINCIPAL_TRANSFORMER_NAME) + .principalTransformers(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME, + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .build(); + + AddAggregatePrincipalTransformer addAggregatePrincipalTransformer2 + = new AddAggregatePrincipalTransformer.Builder(TEST_AGGREGATE_PRINCIPAL_TRANSFORMER_NAME) + .principalTransformers(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2, + TEST_DIFFERENT_PRINCIPAL_TRANSFORMER_NAME) + .replaceExisting() + .build(); + + client.apply(addAggregatePrincipalTransformer); + assertTrue("Aggregate-principal-transformer should be created", + ops.exists(TEST_AGGREGATE_PRINCIPAL_TRANSFORMER_ADDRESS)); + + client.apply(addAggregatePrincipalTransformer2); + assertTrue("Aggregate-principal-transformer should be created", + ops.exists(TEST_AGGREGATE_PRINCIPAL_TRANSFORMER_ADDRESS)); + checkAttribute(TEST_AGGREGATE_PRINCIPAL_TRANSFORMER_ADDRESS, "principal-transformers", + PRINCIPAL_TRANSFORMERS_2_AND_DIFFERENT); + } + + @Test(expected = CommandFailedException.class) + public void addAggregatePrincipalTransformerWithoutConfiguredPrincipalTransformers() throws Exception { + AddAggregatePrincipalTransformer addAggregatePrincipalTransformer + = new AddAggregatePrincipalTransformer.Builder(TEST_AGGREGATE_PRINCIPAL_TRANSFORMER_NAME) + .principalTransformers(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME, "NotConfiguredPrincipalTransformer") + .build(); + + client.apply(addAggregatePrincipalTransformer); + fail("Aggregate-principal-transformer shouldn't be added when using unconfigured principal transformer"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregatePrincipalTransformer_nullName() throws Exception { + new AddAggregatePrincipalTransformer.Builder(null) + .principalTransformers(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME, + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregatePrincipalTransformer_emptyName() throws Exception { + new AddAggregatePrincipalTransformer.Builder("") + .principalTransformers(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME, + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregatePrincipalTransformer_nullPrincipalTransformers() throws Exception { + new AddAggregatePrincipalTransformer.Builder(TEST_AGGREGATE_PRINCIPAL_TRANSFORMER_NAME) + .principalTransformers(null) + .build(); + fail("Creating command with null principal-transformers should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregatePrincipalTransformer_emptyPrincipalTransformers() throws Exception { + new AddAggregatePrincipalTransformer.Builder(TEST_AGGREGATE_PRINCIPAL_TRANSFORMER_NAME) + .principalTransformers("") + .build(); + fail("Creating command with empty principal-transformers should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregatePrincipalTransformer_onePrincipalTransformer() throws Exception { + new AddAggregatePrincipalTransformer.Builder(TEST_AGGREGATE_PRINCIPAL_TRANSFORMER_NAME) + .principalTransformers(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME) + .build(); + fail("Creating command with only one principal-transformer should throw exception"); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAggregateRoleMapperOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAggregateRoleMapperOnlineTest.java new file mode 100644 index 00000000..bc8fac7f --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddAggregateRoleMapperOnlineTest.java @@ -0,0 +1,202 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.OperationException; + +@RunWith(Arquillian.class) +public class AddAggregateRoleMapperOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_AGGREGATE_ROLE_MAPPER_NAME = "CreaperTestAggregateRoleMapper"; + private static final Address TEST_AGGREGATE_ROLE_MAPPER_ADDRESS = SUBSYSTEM_ADDRESS.and("aggregate-role-mapper", + TEST_AGGREGATE_ROLE_MAPPER_NAME); + private static final String TEST_AGGREGATE_ROLE_MAPPER_NAME2 = "CreaperTestAggregateRoleMapper2"; + private static final Address TEST_AGGREGATE_ROLE_MAPPER_ADDRESS2 = SUBSYSTEM_ADDRESS.and("aggregate-role-mapper", + TEST_AGGREGATE_ROLE_MAPPER_NAME2); + + private static final String ADD_PREFIX_ROLE_MAPPER_TYPE = "add-prefix-role-mapper"; + private static final String ADD_SUFFIX_ROLE_MAPPER_TYPE = "add-suffix-role-mapper"; + private static final String TEST_DEFAULT_ADD_PREFIX_ROLE_MAPPER_NAME = "CreaperTestAddPrefixRoleMapper"; + private static final String TEST_DEFAULT_ADD_SUFFIX_ROLE_MAPPER_NAME = "CreaperTestAddSuffixRoleMapper"; + + public AddAggregateRoleMapperOnlineTest() { + super(); + } + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_AGGREGATE_ROLE_MAPPER_ADDRESS); + ops.removeIfExists(TEST_AGGREGATE_ROLE_MAPPER_ADDRESS2); + + removeAllAddPrefixRoleMappers(); + removeAllAddSuffixRoleMappers(); + + administration.reloadIfRequired(); + } + + @Test + public void addAggregateRoleMapper() throws Exception { + addDefaultPrefixMapper(); + addDefaultSuffixMapper(); + + AddAggregateRoleMapper addAggregateRoleMapper = + new AddAggregateRoleMapper.Builder(TEST_AGGREGATE_ROLE_MAPPER_NAME) + .addRoleMappers(TEST_DEFAULT_ADD_PREFIX_ROLE_MAPPER_NAME, TEST_DEFAULT_ADD_PREFIX_ROLE_MAPPER_NAME) + .build(); + + client.apply(addAggregateRoleMapper); + + assertTrue("Aggregate role mapper should be created", ops.exists(TEST_AGGREGATE_ROLE_MAPPER_ADDRESS)); + } + + @Test + public void addAggregateRoleMapper_duplicateRoleMapper() throws Exception { + addDefaultPrefixMapper(); + + AddAggregateRoleMapper addAggregateRoleMapper = + new AddAggregateRoleMapper.Builder(TEST_AGGREGATE_ROLE_MAPPER_NAME) + .addRoleMappers(TEST_DEFAULT_ADD_PREFIX_ROLE_MAPPER_NAME, TEST_DEFAULT_ADD_PREFIX_ROLE_MAPPER_NAME) + .build(); + + client.apply(addAggregateRoleMapper); + + assertTrue("Aggregate role mapper should be created", ops.exists(TEST_AGGREGATE_ROLE_MAPPER_ADDRESS)); + } + + @Test(expected = CommandFailedException.class) + public void addAggregateRoleMapper_oneRoleMapper() throws Exception { + addDefaultPrefixMapper(); + + AddAggregateRoleMapper addAggregateRoleMapper = + new AddAggregateRoleMapper.Builder(TEST_AGGREGATE_ROLE_MAPPER_NAME) + .addRoleMappers(TEST_DEFAULT_ADD_PREFIX_ROLE_MAPPER_NAME).build(); + + client.apply(addAggregateRoleMapper); + + fail("Creating command with only one role mapper should throw exception"); + } + + @Test(expected = CommandFailedException.class) + public void addAggregateRoleMapper_nonExistingRoleMappers() throws Exception { + AddAggregateRoleMapper addAggregateRoleMapper = + new AddAggregateRoleMapper.Builder(TEST_AGGREGATE_ROLE_MAPPER_NAME) + .addRoleMappers("nonExistsRoleMapper1", "nonExistsRoleMapper2").build(); + + client.apply(addAggregateRoleMapper); + + fail("Creating command with non existing role mappers should throw exception"); + } + + @Test + public void addAggregateRoleMappers() throws Exception { + addPrefixMapper("prefixMapper1", "prefix1"); + addPrefixMapper("prefixMapper2", "prefix2"); + addSuffixMapper("suffixMapper1", "suffix1"); + addSuffixMapper("suffixMapper2", "suffix2"); + + AddAggregateRoleMapper addAggregateRoleMapper = + new AddAggregateRoleMapper.Builder(TEST_AGGREGATE_ROLE_MAPPER_NAME) + .addRoleMappers("prefixMapper1", "prefixMapper2") + .build(); + + AddAggregateRoleMapper addAggregateRoleMapper2 = + new AddAggregateRoleMapper.Builder(TEST_AGGREGATE_ROLE_MAPPER_NAME2) + .addRoleMappers("suffixMapper1", "suffixMapper2") + .build(); + + client.apply(addAggregateRoleMapper); + client.apply(addAggregateRoleMapper2); + + assertTrue("Aggregate role mapper should be created", ops.exists(TEST_AGGREGATE_ROLE_MAPPER_ADDRESS)); + assertTrue("Second aggregate role mapper should be created", ops.exists(TEST_AGGREGATE_ROLE_MAPPER_ADDRESS2)); + + assertRolesMappers(TEST_AGGREGATE_ROLE_MAPPER_ADDRESS, "prefixMapper1", "prefixMapper2"); + assertRolesMappers(TEST_AGGREGATE_ROLE_MAPPER_ADDRESS2, "suffixMapper1", "suffixMapper2"); + + administration.reload(); + + assertRolesMappers(TEST_AGGREGATE_ROLE_MAPPER_ADDRESS, "prefixMapper1", "prefixMapper2"); + assertRolesMappers(TEST_AGGREGATE_ROLE_MAPPER_ADDRESS2, "suffixMapper1", "suffixMapper2"); + } + + @Test(expected = CommandFailedException.class) + public void addDuplicateAggregateRoleMapperNotAllowed() throws Exception { + addPrefixMapper("prefixMapper1", "prefix1"); + + AddAggregateRoleMapper addAggregateRoleMapper = + new AddAggregateRoleMapper.Builder(TEST_AGGREGATE_ROLE_MAPPER_NAME) + .addRoleMappers("prefixMapper1") + .build(); + + client.apply(addAggregateRoleMapper); + assertTrue("Aggregate role mapper should be created", ops.exists(TEST_AGGREGATE_ROLE_MAPPER_ADDRESS)); + client.apply(addAggregateRoleMapper); + fail("Aggregate role mapper " + TEST_AGGREGATE_ROLE_MAPPER_NAME + + " already exists in configuration, exception should be thrown"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregateRoleMapper_nullName() throws Exception { + new AddAggregateRoleMapper.Builder(null); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregateRoleMapper_emptyName() throws Exception { + new AddAggregateRoleMapper.Builder(""); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregateRoleMapper_noRoleMapper() throws Exception { + new AddAggregateRoleMapper.Builder(TEST_AGGREGATE_ROLE_MAPPER_NAME).build(); + fail("Creating command with no role mapper should throw exception"); + } + + private void assertRolesMappers(Address address, String... expectedRoleMappers) throws Exception { + List actualRolesMappers = ops.readAttribute(address, "role-mappers").stringListValue(); + assertEquals("Unexpected role mappers attribute value in " + + address, Arrays.asList(expectedRoleMappers), actualRolesMappers); + } + + private void addDefaultPrefixMapper() throws CommandFailedException { + addPrefixMapper(TEST_DEFAULT_ADD_PREFIX_ROLE_MAPPER_NAME, "somePrefix"); + } + + private void addPrefixMapper(String roleMapperName, String prefix) throws CommandFailedException { + AddAddPrefixRoleMapper addAddPrefixRoleMapper = new AddAddPrefixRoleMapper.Builder(roleMapperName) + .prefix(prefix).build(); + client.apply(addAddPrefixRoleMapper); + } + + private void addDefaultSuffixMapper() throws CommandFailedException { + addSuffixMapper(TEST_DEFAULT_ADD_SUFFIX_ROLE_MAPPER_NAME, "someSuffix"); + } + + private void addSuffixMapper(String roleMapperName, String suffix) throws CommandFailedException { + AddAddSuffixRoleMapper addAddSuffixRoleMapper = new AddAddSuffixRoleMapper.Builder(roleMapperName) + .suffix(suffix).build(); + client.apply(addAddSuffixRoleMapper); + } + + private void removeAllAddPrefixRoleMappers() throws IOException, OperationException { + removeAllElytronChildrenType(ADD_PREFIX_ROLE_MAPPER_TYPE); + } + + private void removeAllAddSuffixRoleMappers() throws IOException, OperationException { + removeAllElytronChildrenType(ADD_SUFFIX_ROLE_MAPPER_TYPE); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddChainedPrincipalTransformerOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddChainedPrincipalTransformerOnlineTest.java new file mode 100644 index 00000000..856f2b54 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddChainedPrincipalTransformerOnlineTest.java @@ -0,0 +1,171 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.wildfly.extras.creaper.commands.elytron.mapper.AbstractAddPrincipalTransformerOnlineTest.TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME; + +@RunWith(Arquillian.class) +public class AddChainedPrincipalTransformerOnlineTest extends AbstractAddPrincipalTransformerOnlineTest { + + private static final String TEST_CHAINED_PRINCIPAL_TRANSFORMER_NAME = "CreaperTestChainedPrincipalTransformer"; + private static final Address TEST_CHAINED_PRINCIPAL_TRANSFORMER_ADDRESS = SUBSYSTEM_ADDRESS + .and("chained-principal-transformer", TEST_CHAINED_PRINCIPAL_TRANSFORMER_NAME); + private static final String TEST_CHAINED_PRINCIPAL_TRANSFORMER_NAME2 = "CreaperTestChainedPrincipalTransformer2"; + private static final Address TEST_CHAINED_PRINCIPAL_TRANSFORMER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("chained-principal-transformer", TEST_CHAINED_PRINCIPAL_TRANSFORMER_NAME2); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_CHAINED_PRINCIPAL_TRANSFORMER_ADDRESS); + ops.removeIfExists(TEST_CHAINED_PRINCIPAL_TRANSFORMER_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addChainedPrincipalTransformer() throws Exception { + AddChainedPrincipalTransformer addChainedPrincipalTransformer + = new AddChainedPrincipalTransformer.Builder(TEST_CHAINED_PRINCIPAL_TRANSFORMER_NAME) + .principalTransformers(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME, + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .build(); + + client.apply(addChainedPrincipalTransformer); + + assertTrue("Chained-principal-transformer should be created", + ops.exists(TEST_CHAINED_PRINCIPAL_TRANSFORMER_ADDRESS)); + checkAttribute(TEST_CHAINED_PRINCIPAL_TRANSFORMER_ADDRESS, "principal-transformers", + PRINCIPAL_TRANSFORMERS_1_AND_2); + } + + @Test + public void addTwoChainedPrincipalTransformers() throws Exception { + AddChainedPrincipalTransformer addChainedPrincipalTransformer + = new AddChainedPrincipalTransformer.Builder(TEST_CHAINED_PRINCIPAL_TRANSFORMER_NAME) + .principalTransformers(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME, + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .build(); + + AddChainedPrincipalTransformer addChainedPrincipalTransformer2 + = new AddChainedPrincipalTransformer.Builder(TEST_CHAINED_PRINCIPAL_TRANSFORMER_NAME2) + .principalTransformers(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2, + TEST_DIFFERENT_PRINCIPAL_TRANSFORMER_NAME) + .build(); + + client.apply(addChainedPrincipalTransformer); + client.apply(addChainedPrincipalTransformer2); + + assertTrue("Chained-principal-transformer should be created", + ops.exists(TEST_CHAINED_PRINCIPAL_TRANSFORMER_ADDRESS)); + assertTrue("Chained-principal-transformer should be created", + ops.exists(TEST_CHAINED_PRINCIPAL_TRANSFORMER_ADDRESS2)); + } + + @Test(expected = CommandFailedException.class) + public void addExistChainedPrincipalTransformersNotAllowed() throws Exception { + AddChainedPrincipalTransformer addChainedPrincipalTransformer + = new AddChainedPrincipalTransformer.Builder(TEST_CHAINED_PRINCIPAL_TRANSFORMER_NAME) + .principalTransformers(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME, + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .build(); + + AddChainedPrincipalTransformer addChainedPrincipalTransformer2 + = new AddChainedPrincipalTransformer.Builder(TEST_CHAINED_PRINCIPAL_TRANSFORMER_NAME) + .principalTransformers(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2, + TEST_DIFFERENT_PRINCIPAL_TRANSFORMER_NAME) + .build(); + + client.apply(addChainedPrincipalTransformer); + assertTrue("Chained-principal-transformer should be created", + ops.exists(TEST_CHAINED_PRINCIPAL_TRANSFORMER_ADDRESS)); + + client.apply(addChainedPrincipalTransformer2); + fail("Chained-principal-transformer CreaperTestChainedPrincipalTransformer already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistChainedPrincipalTransformersAllowed() throws Exception { + AddChainedPrincipalTransformer addChainedPrincipalTransformer + = new AddChainedPrincipalTransformer.Builder(TEST_CHAINED_PRINCIPAL_TRANSFORMER_NAME) + .principalTransformers(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME, + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .build(); + + AddChainedPrincipalTransformer addChainedPrincipalTransformer2 + = new AddChainedPrincipalTransformer.Builder(TEST_CHAINED_PRINCIPAL_TRANSFORMER_NAME) + .principalTransformers(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2, + TEST_DIFFERENT_PRINCIPAL_TRANSFORMER_NAME) + .replaceExisting() + .build(); + + client.apply(addChainedPrincipalTransformer); + assertTrue("Chained-principal-transformer should be created", + ops.exists(TEST_CHAINED_PRINCIPAL_TRANSFORMER_ADDRESS)); + + client.apply(addChainedPrincipalTransformer2); + assertTrue("Chained-principal-transformer should be created", + ops.exists(TEST_CHAINED_PRINCIPAL_TRANSFORMER_ADDRESS)); + checkAttribute(TEST_CHAINED_PRINCIPAL_TRANSFORMER_ADDRESS, "principal-transformers", + PRINCIPAL_TRANSFORMERS_2_AND_DIFFERENT); + } + + @Test(expected = CommandFailedException.class) + public void addChainedPrincipalTransformerWithoutConfiguredPrincipalTransformers() throws Exception { + AddChainedPrincipalTransformer addChainedPrincipalTransformer + = new AddChainedPrincipalTransformer.Builder(TEST_CHAINED_PRINCIPAL_TRANSFORMER_NAME) + .principalTransformers(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME, "NotConfiguredPrincipalTransformer") + .build(); + + client.apply(addChainedPrincipalTransformer); + fail("Chained-principal-transformer shouldn't be added when using unconfigured principal transformer"); + } + + @Test(expected = IllegalArgumentException.class) + public void addChainedPrincipalTransformer_nullName() throws Exception { + new AddChainedPrincipalTransformer.Builder(null) + .principalTransformers(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME, + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addChainedPrincipalTransformer_emptyName() throws Exception { + new AddChainedPrincipalTransformer.Builder("") + .principalTransformers(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME, + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addChainedPrincipalTransformer_nullPrincipalTransformers() throws Exception { + new AddChainedPrincipalTransformer.Builder(TEST_CHAINED_PRINCIPAL_TRANSFORMER_NAME) + .principalTransformers(null) + .build(); + fail("Creating command with null principal-transformers should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addChainedPrincipalTransformer_emptyPrincipalTransformers() throws Exception { + new AddChainedPrincipalTransformer.Builder(TEST_CHAINED_PRINCIPAL_TRANSFORMER_NAME) + .principalTransformers("") + .build(); + fail("Creating command with empty principal-transformers should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addChainedPrincipalTransformer_onePrincipalTransformer() throws Exception { + new AddChainedPrincipalTransformer.Builder(TEST_CHAINED_PRINCIPAL_TRANSFORMER_NAME) + .principalTransformers(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME) + .build(); + fail("Creating command with only one principal-transformer should throw exception"); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConcatenatingPrincipalDecoderOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConcatenatingPrincipalDecoderOnlineTest.java new file mode 100644 index 00000000..f99c72a5 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConcatenatingPrincipalDecoderOnlineTest.java @@ -0,0 +1,173 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import java.io.IOException; +import java.util.List; +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +@RunWith(Arquillian.class) +public class AddConcatenatingPrincipalDecoderOnlineTest extends AbstractAddPrincipalDecoderOnlineTest { + + private static final String TEST_CONCATENATING_PRINCIPAL_DECODER_NAME = "CreaperTestConcatenatingPrincipalDecoder"; + private static final Address TEST_CONCATENATING_PRINCIPAL_DECODER_ADDRESS = SUBSYSTEM_ADDRESS + .and("concatenating-principal-decoder", TEST_CONCATENATING_PRINCIPAL_DECODER_NAME); + private static final String TEST_CONCATENATING_PRINCIPAL_DECODER_NAME2 = "CreaperTestConcatenatingPrincipalDecoder2"; + private static final Address TEST_CONCATENATING_PRINCIPAL_DECODER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("concatenating-principal-decoder", TEST_CONCATENATING_PRINCIPAL_DECODER_NAME2); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_CONCATENATING_PRINCIPAL_DECODER_ADDRESS); + ops.removeIfExists(TEST_CONCATENATING_PRINCIPAL_DECODER_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addConcatenatingPrincipalDecoder() throws Exception { + AddConcatenatingPrincipalDecoder addConcatenatingPricipalDecoder + = new AddConcatenatingPrincipalDecoder.Builder(TEST_CONCATENATING_PRINCIPAL_DECODER_NAME) + .joiner(".") + .principalDecoders(TEST_CONSTANT_PRINCIPAL_DECODER_NAME, TEST_CONSTANT_PRINCIPAL_DECODER_NAME2) + .build(); + + client.apply(addConcatenatingPricipalDecoder); + + assertTrue("Concatenating-principal-decoder should be created", + ops.exists(TEST_CONCATENATING_PRINCIPAL_DECODER_ADDRESS)); + checkConcatenatingPrincipalDecoderAttribute("joiner", "."); + checkConcatenatingPrincipalDecoderAttribute("principal-decoders", PRINCIPAL_DECODERS_1_AND_2); + } + + @Test + public void addTwoConcatenatingPrincipalDecoders() throws Exception { + AddConcatenatingPrincipalDecoder addConcatenatingPricipalDecoder + = new AddConcatenatingPrincipalDecoder.Builder(TEST_CONCATENATING_PRINCIPAL_DECODER_NAME) + .principalDecoders(TEST_CONSTANT_PRINCIPAL_DECODER_NAME, TEST_CONSTANT_PRINCIPAL_DECODER_NAME2) + .build(); + + AddConcatenatingPrincipalDecoder addConcatenatingPricipalDecoder2 + = new AddConcatenatingPrincipalDecoder.Builder(TEST_CONCATENATING_PRINCIPAL_DECODER_NAME2) + .principalDecoders(TEST_CONSTANT_PRINCIPAL_DECODER_NAME, TEST_CONSTANT_PRINCIPAL_DECODER_NAME2) + .build(); + + client.apply(addConcatenatingPricipalDecoder); + client.apply(addConcatenatingPricipalDecoder2); + + assertTrue("Concatenating-principal-decoder should be created", + ops.exists(TEST_CONCATENATING_PRINCIPAL_DECODER_ADDRESS)); + assertTrue("Concatenating-principal-decoder should be created", + ops.exists(TEST_CONCATENATING_PRINCIPAL_DECODER_ADDRESS2)); + } + + @Test(expected = CommandFailedException.class) + public void addExistConcatenatingPrincipalDecodersNotAllowed() throws Exception { + AddConcatenatingPrincipalDecoder addConcatenatingPricipalDecoder + = new AddConcatenatingPrincipalDecoder.Builder(TEST_CONCATENATING_PRINCIPAL_DECODER_NAME) + .principalDecoders(TEST_CONSTANT_PRINCIPAL_DECODER_NAME, TEST_CONSTANT_PRINCIPAL_DECODER_NAME2) + .build(); + + AddConcatenatingPrincipalDecoder addConcatenatingPricipalDecoder2 + = new AddConcatenatingPrincipalDecoder.Builder(TEST_CONCATENATING_PRINCIPAL_DECODER_NAME) + .principalDecoders(TEST_CONSTANT_PRINCIPAL_DECODER_NAME, TEST_CONSTANT_PRINCIPAL_DECODER_NAME2) + .build(); + + client.apply(addConcatenatingPricipalDecoder); + assertTrue("Concatenating-principal-decoder should be created", + ops.exists(TEST_CONCATENATING_PRINCIPAL_DECODER_ADDRESS)); + + client.apply(addConcatenatingPricipalDecoder2); + fail("Concatenating-principal-decoder CreaperTestConcatenatingPrincipalDecoder already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistConcatenatingPrincipalDecodersAllowed() throws Exception { + AddConcatenatingPrincipalDecoder addConcatenatingPricipalDecoder + = new AddConcatenatingPrincipalDecoder.Builder(TEST_CONCATENATING_PRINCIPAL_DECODER_NAME) + .principalDecoders(TEST_CONSTANT_PRINCIPAL_DECODER_NAME, TEST_CONSTANT_PRINCIPAL_DECODER_NAME2) + .build(); + + AddConcatenatingPrincipalDecoder addConcatenatingPricipalDecoder2 + = new AddConcatenatingPrincipalDecoder.Builder(TEST_CONCATENATING_PRINCIPAL_DECODER_NAME) + .joiner("::") + .principalDecoders(TEST_CONSTANT_PRINCIPAL_DECODER_NAME2, TEST_DIFFERENT_PRINCIPAL_DECODER_NAME) + .replaceExisting() + .build(); + + client.apply(addConcatenatingPricipalDecoder); + assertTrue("Concatenating-principal-decoder should be created", + ops.exists(TEST_CONCATENATING_PRINCIPAL_DECODER_ADDRESS)); + + client.apply(addConcatenatingPricipalDecoder2); + assertTrue("Concatenating-principal-decoder should be created", + ops.exists(TEST_CONCATENATING_PRINCIPAL_DECODER_ADDRESS)); + checkConcatenatingPrincipalDecoderAttribute("joiner", "::"); + checkConcatenatingPrincipalDecoderAttribute("principal-decoders", PRINCIPAL_DECODERS_2_AND_DIFFERENT); + } + + @Test(expected = CommandFailedException.class) + public void addConcatenatingPrincipalDecoderWithoutConfiguredPrincipalsDecoders() throws Exception { + AddConcatenatingPrincipalDecoder addConcatenatingPricipalDecoder + = new AddConcatenatingPrincipalDecoder.Builder(TEST_CONCATENATING_PRINCIPAL_DECODER_NAME) + .joiner(".") + .principalDecoders(TEST_CONSTANT_PRINCIPAL_DECODER_NAME, "NotConfiguredPrincipalDecoder") + .build(); + + client.apply(addConcatenatingPricipalDecoder); + fail("Concatenating-principal-decoder shouldn't be added when using unconfigured principal decoder"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConcatenatingPrincipalDecoder_nullName() throws Exception { + new AddConcatenatingPrincipalDecoder.Builder(null) + .principalDecoders(TEST_CONSTANT_PRINCIPAL_DECODER_NAME, TEST_CONSTANT_PRINCIPAL_DECODER_NAME2) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConcatenatingPrincipalDecoder_emptyName() throws Exception { + new AddConcatenatingPrincipalDecoder.Builder("") + .principalDecoders(TEST_CONSTANT_PRINCIPAL_DECODER_NAME, TEST_CONSTANT_PRINCIPAL_DECODER_NAME2) + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConcatenatingPrincipalDecoder_nullPrincipalDecoders() throws Exception { + new AddConcatenatingPrincipalDecoder.Builder(TEST_CONCATENATING_PRINCIPAL_DECODER_NAME) + .principalDecoders(null) + .build(); + fail("Creating command with null principal-decoders should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConcatenatingPrincipalDecoder_emptyPrincipalDecoders() throws Exception { + new AddConcatenatingPrincipalDecoder.Builder(TEST_CONCATENATING_PRINCIPAL_DECODER_NAME) + .principalDecoders("") + .build(); + fail("Creating command with empty principal-decoders should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConcatenatingPrincipalDecoder_onePrincipalDecoder() throws Exception { + new AddConcatenatingPrincipalDecoder.Builder(TEST_CONCATENATING_PRINCIPAL_DECODER_NAME) + .principalDecoders(TEST_CONSTANT_PRINCIPAL_DECODER_NAME) + .build(); + fail("Creating command with only one principal-decoder should throw exception"); + } + + private void checkConcatenatingPrincipalDecoderAttribute(String attr, String expected) throws IOException { + checkAttribute(TEST_CONCATENATING_PRINCIPAL_DECODER_ADDRESS, attr, expected); + } + + private void checkConcatenatingPrincipalDecoderAttribute(String attr, List expected) throws IOException { + checkAttribute(TEST_CONCATENATING_PRINCIPAL_DECODER_ADDRESS, attr, expected); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantPermissionMapperOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantPermissionMapperOnlineTest.java new file mode 100644 index 00000000..ab40ad87 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantPermissionMapperOnlineTest.java @@ -0,0 +1,200 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.ModelNodeResult; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddConstantPermissionMapperOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_CONSTANT_PERMISSION_MAPPER_NAME = "CreaperTestConstantPermissionMapper"; + private static final Address TEST_CONSTANT_PERMISSION_MAPPER_ADDRESS = SUBSYSTEM_ADDRESS + .and("constant-permission-mapper", TEST_CONSTANT_PERMISSION_MAPPER_NAME); + private static final String TEST_CONSTANT_PERMISSION_MAPPER_NAME2 = "CreaperTestConstantPermissionMapper2"; + private static final Address TEST_CONSTANT_PERMISSION_MAPPER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("constant-permission-mapper", TEST_CONSTANT_PERMISSION_MAPPER_NAME2); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_CONSTANT_PERMISSION_MAPPER_ADDRESS); + ops.removeIfExists(TEST_CONSTANT_PERMISSION_MAPPER_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleConstantPermissionMapper() throws Exception { + AddConstantPermissionMapper addConstantPermissionMapper + = new AddConstantPermissionMapper.Builder(TEST_CONSTANT_PERMISSION_MAPPER_NAME) + .addPermissions(new AddConstantPermissionMapper.PermissionBuilder() + .className("org.wildfly.security.auth.permission.LoginPermission") + .build()) + .build(); + + client.apply(addConstantPermissionMapper); + + assertTrue("Constant permission mapper should be created", + ops.exists(TEST_CONSTANT_PERMISSION_MAPPER_ADDRESS)); + } + + @Test + public void addTwoConstantPermissionMappers() throws Exception { + AddConstantPermissionMapper addConstantPermissionMapper + = new AddConstantPermissionMapper.Builder(TEST_CONSTANT_PERMISSION_MAPPER_NAME) + .addPermissions(new AddConstantPermissionMapper.PermissionBuilder() + .className("org.wildfly.security.auth.permission.LoginPermission") + .build()) + .build(); + + AddConstantPermissionMapper addConstantPermissionMapper2 + = new AddConstantPermissionMapper.Builder(TEST_CONSTANT_PERMISSION_MAPPER_NAME2) + .addPermissions(new AddConstantPermissionMapper.PermissionBuilder() + .className("org.wildfly.security.auth.permission.LoginPermission") + .build()) + .build(); + + client.apply(addConstantPermissionMapper); + client.apply(addConstantPermissionMapper2); + + assertTrue("Constant permission mapper should be created", + ops.exists(TEST_CONSTANT_PERMISSION_MAPPER_ADDRESS)); + assertTrue("Second constant permission mapper should be created", + ops.exists(TEST_CONSTANT_PERMISSION_MAPPER_ADDRESS2)); + } + + @Test + public void addFullConstantPermissionMapper() throws Exception { + AddConstantPermissionMapper addConstantPermissionMapper + = new AddConstantPermissionMapper.Builder(TEST_CONSTANT_PERMISSION_MAPPER_NAME) + .addPermissions(new AddConstantPermissionMapper.PermissionBuilder() + .className("org.wildfly.security.auth.permission.LoginPermission") + .action("login") + .targetName("loginPermissionName") + .build(), + new AddConstantPermissionMapper.PermissionBuilder() + .className("org.wildfly.security.auth.permission.RunAsPrincipalPermission") + .action("read") + .targetName("runAsPrincipalPermissionName") + .build()) + .build(); + + client.apply(addConstantPermissionMapper); + assertTrue("Constant permission mapper should be created", + ops.exists(TEST_CONSTANT_PERMISSION_MAPPER_ADDRESS)); + + checkConstantPermissionMapperAttribute("permissions[0].class-name", + "org.wildfly.security.auth.permission.LoginPermission"); + checkConstantPermissionMapperAttribute("permissions[0].action", "login"); + checkConstantPermissionMapperAttribute("permissions[0].target-name", "loginPermissionName"); + + checkConstantPermissionMapperAttribute("permissions[1].class-name", + "org.wildfly.security.auth.permission.RunAsPrincipalPermission"); + checkConstantPermissionMapperAttribute("permissions[1].action", "read"); + checkConstantPermissionMapperAttribute("permissions[1].target-name", "runAsPrincipalPermissionName"); + } + + @Test(expected = CommandFailedException.class) + public void addExistConstantPermissionMapperNotAllowed() throws Exception { + AddConstantPermissionMapper addConstantPermissionMapper + = new AddConstantPermissionMapper.Builder(TEST_CONSTANT_PERMISSION_MAPPER_NAME) + .addPermissions(new AddConstantPermissionMapper.PermissionBuilder() + .className("org.wildfly.security.auth.permission.LoginPermission") + .build()) + .build(); + + AddConstantPermissionMapper addConstantPermissionMapper2 + = new AddConstantPermissionMapper.Builder(TEST_CONSTANT_PERMISSION_MAPPER_NAME) + .addPermissions(new AddConstantPermissionMapper.PermissionBuilder() + .className("org.wildfly.security.auth.permission.ChangeRoleMapperPermission") + .targetName("someName") + .build()) + .build(); + + client.apply(addConstantPermissionMapper); + assertTrue("Constant permission mapper should be created", + ops.exists(TEST_CONSTANT_PERMISSION_MAPPER_ADDRESS)); + client.apply(addConstantPermissionMapper2); + fail("Constant permission mapper CreaperTestConstantPermissionMapper already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistConstantPermissionMapperAllowed() throws Exception { + AddConstantPermissionMapper addConstantPermissionMapper + = new AddConstantPermissionMapper.Builder(TEST_CONSTANT_PERMISSION_MAPPER_NAME) + .addPermissions(new AddConstantPermissionMapper.PermissionBuilder() + .className("org.wildfly.security.auth.permission.LoginPermission") + .build()) + .build(); + + AddConstantPermissionMapper addConstantPermissionMapper2 + = new AddConstantPermissionMapper.Builder(TEST_CONSTANT_PERMISSION_MAPPER_NAME) + .addPermissions(new AddConstantPermissionMapper.PermissionBuilder() + .className("org.wildfly.security.auth.permission.ChangeRoleMapperPermission") + .targetName("someName") + .build()) + .replaceExisting() + .build(); + + client.apply(addConstantPermissionMapper); + assertTrue("Constant permission mapper should be created", + ops.exists(TEST_CONSTANT_PERMISSION_MAPPER_ADDRESS)); + client.apply(addConstantPermissionMapper2); + assertTrue("Constant permission mapper should be created", + ops.exists(TEST_CONSTANT_PERMISSION_MAPPER_ADDRESS)); + // check whether it was really rewritten + checkConstantPermissionMapperAttribute("permissions[0].class-name", + "org.wildfly.security.auth.permission.ChangeRoleMapperPermission"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConstantPermissionMapper_nullName() throws Exception { + new AddConstantPermissionMapper.Builder(null) + .addPermissions(new AddConstantPermissionMapper.PermissionBuilder() + .className("org.wildfly.security.auth.permission.LoginPermission") + .build()) + .build(); + } + + @Test(expected = IllegalArgumentException.class) + public void addConstantPermissionMapper_emptyName() throws Exception { + new AddConstantPermissionMapper.Builder("") + .addPermissions(new AddConstantPermissionMapper.PermissionBuilder() + .className("org.wildfly.security.auth.permission.LoginPermission") + .build()) + .build(); + } + + @Test(expected = IllegalArgumentException.class) + public void addConstantPermissionMapper_nullClassName() throws Exception { + new AddConstantPermissionMapper.Builder(TEST_CONSTANT_PERMISSION_MAPPER_NAME) + .addPermissions(new AddConstantPermissionMapper.PermissionBuilder() + .className(null) + .build()) + .build(); + } + + @Test(expected = IllegalArgumentException.class) + public void addConstantPermissionMapper_emptyClassName() throws Exception { + new AddConstantPermissionMapper.Builder(TEST_CONSTANT_PERMISSION_MAPPER_NAME) + .addPermissions(new AddConstantPermissionMapper.PermissionBuilder() + .className("") + .build()) + .build(); + } + + private void checkConstantPermissionMapperAttribute(String attribute, String expectedValue) throws IOException { + ModelNodeResult readAttribute = ops.readAttribute(TEST_CONSTANT_PERMISSION_MAPPER_ADDRESS, attribute); + readAttribute.assertSuccess("Read operation for " + attribute + " failed"); + assertEquals("Read operation for " + attribute + " return wrong value", expectedValue, + readAttribute.stringValue()); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantPrincipalDecoderOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantPrincipalDecoderOnlineTest.java new file mode 100644 index 00000000..a91002d4 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantPrincipalDecoderOnlineTest.java @@ -0,0 +1,138 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import java.io.IOException; +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +@RunWith(Arquillian.class) +public class AddConstantPrincipalDecoderOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_CONSTANT_PRINCIPAL_DECODER_NAME = "CreaperTestConstantPrincipalDecoder"; + private static final Address TEST_CONSTANT_PRINCIPAL_DECODER_ADDRESS = SUBSYSTEM_ADDRESS + .and("constant-principal-decoder", TEST_CONSTANT_PRINCIPAL_DECODER_NAME); + private static final String TEST_CONSTANT_PRINCIPAL_DECODER_NAME2 = "CreaperTestConstantPrincipalDecoder2"; + private static final Address TEST_CONSTANT_PRINCIPAL_DECODER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("constant-principal-decoder", TEST_CONSTANT_PRINCIPAL_DECODER_NAME2); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_CONSTANT_PRINCIPAL_DECODER_ADDRESS); + ops.removeIfExists(TEST_CONSTANT_PRINCIPAL_DECODER_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addConstantPrincipalDecoder() throws Exception { + AddConstantPrincipalDecoder addConstantPrincipalDecoder + = new AddConstantPrincipalDecoder.Builder(TEST_CONSTANT_PRINCIPAL_DECODER_NAME) + .constant("role1") + .build(); + + client.apply(addConstantPrincipalDecoder); + + assertTrue("Constant principal decoder should be created", ops.exists(TEST_CONSTANT_PRINCIPAL_DECODER_ADDRESS)); + } + + @Test + public void addTwoConstantPrincipalDecoders() throws Exception { + AddConstantPrincipalDecoder addConstantPrincipalDecoder + = new AddConstantPrincipalDecoder.Builder(TEST_CONSTANT_PRINCIPAL_DECODER_NAME) + .constant("role1") + .build(); + AddConstantPrincipalDecoder addConstantPrincipalDecoder2 + = new AddConstantPrincipalDecoder.Builder(TEST_CONSTANT_PRINCIPAL_DECODER_NAME2) + .constant("role2") + .build(); + + client.apply(addConstantPrincipalDecoder); + client.apply(addConstantPrincipalDecoder2); + + assertTrue("Constant principal decoder should be created", + ops.exists(TEST_CONSTANT_PRINCIPAL_DECODER_ADDRESS)); + assertTrue("Constant principal decoder should be created", + ops.exists(TEST_CONSTANT_PRINCIPAL_DECODER_ADDRESS2)); + } + + @Test(expected = CommandFailedException.class) + public void addExistConstantPrincipalDecoderNotAllowed() throws Exception { + AddConstantPrincipalDecoder addConstantPrincipalDecoder + = new AddConstantPrincipalDecoder.Builder(TEST_CONSTANT_PRINCIPAL_DECODER_NAME) + .constant("role1") + .build(); + AddConstantPrincipalDecoder addConstantPrincipalDecoder2 + = new AddConstantPrincipalDecoder.Builder(TEST_CONSTANT_PRINCIPAL_DECODER_NAME) + .constant("role1") + .build(); + + client.apply(addConstantPrincipalDecoder); + assertTrue("Constant principal decoder should be created", ops.exists(TEST_CONSTANT_PRINCIPAL_DECODER_ADDRESS)); + + client.apply(addConstantPrincipalDecoder2); + fail("Constant principal decoder CreaperTestConstantPrincipalDecoder already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistConstantPrincipalDecoderAllowed() throws Exception { + AddConstantPrincipalDecoder addConstantPrincipalDecoder + = new AddConstantPrincipalDecoder.Builder(TEST_CONSTANT_PRINCIPAL_DECODER_NAME) + .constant("role1") + .build(); + AddConstantPrincipalDecoder addConstantPrincipalDecoder2 + = new AddConstantPrincipalDecoder.Builder(TEST_CONSTANT_PRINCIPAL_DECODER_NAME) + .constant("role2") + .replaceExisting() + .build(); + + client.apply(addConstantPrincipalDecoder); + assertTrue("Constant principal decoder should be created", ops.exists(TEST_CONSTANT_PRINCIPAL_DECODER_ADDRESS)); + + client.apply(addConstantPrincipalDecoder2); + assertTrue("Constant principal decoder should be created", ops.exists(TEST_CONSTANT_PRINCIPAL_DECODER_ADDRESS)); + + checkConstantPrincipalDecoderConstant("role2"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConstantPrincipalDecoder_nullName() throws Exception { + new AddConstantPrincipalDecoder.Builder(null) + .constant("role1") + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConstantPrincipalDecoder_emptyName() throws Exception { + new AddConstantPrincipalDecoder.Builder("") + .constant("role1") + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConstantPrincipalDecoder_nullConstant() throws Exception { + new AddConstantPrincipalDecoder.Builder(TEST_CONSTANT_PRINCIPAL_DECODER_NAME) + .constant(null) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConstantPrincipalDecoder_emptyConstant() throws Exception { + new AddConstantPrincipalDecoder.Builder(TEST_CONSTANT_PRINCIPAL_DECODER_NAME) + .constant("") + .build(); + fail("Creating command with empty name should throw exception"); + } + + private void checkConstantPrincipalDecoderConstant(String expectedValue) throws IOException { + checkAttribute(TEST_CONSTANT_PRINCIPAL_DECODER_ADDRESS, "constant", expectedValue); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantPrincipalTransformerOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantPrincipalTransformerOnlineTest.java new file mode 100644 index 00000000..7bd84bc6 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantPrincipalTransformerOnlineTest.java @@ -0,0 +1,143 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import java.io.IOException; +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +@RunWith(Arquillian.class) +public class AddConstantPrincipalTransformerOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME = "CreaperTestConstantPrincipalTransformer"; + private static final Address TEST_CONSTANT_PRINCIPAL_TRANSFORMER_ADDRESS = SUBSYSTEM_ADDRESS + .and("constant-principal-transformer", TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME); + private static final String TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2 = "CreaperTestConstantPrincipalTransformer2"; + private static final Address TEST_CONSTANT_PRINCIPAL_TRANSFORMER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("constant-principal-transformer", TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_ADDRESS); + ops.removeIfExists(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addConstantPrincipalTransformer() throws Exception { + AddConstantPrincipalTransformer addConstantPrincipalTransformer + = new AddConstantPrincipalTransformer.Builder(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME) + .constant("name1") + .build(); + + client.apply(addConstantPrincipalTransformer); + + assertTrue("Constant principal transformer should be created", + ops.exists(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_ADDRESS)); + checkConstantPrincipalTransformerConstant("name1"); + } + + @Test + public void addTwoConstantPrincipalTransformers() throws Exception { + AddConstantPrincipalTransformer addConstantPrincipalTransformer + = new AddConstantPrincipalTransformer.Builder(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME) + .constant("name1") + .build(); + AddConstantPrincipalTransformer addConstantPrincipalTransformer2 + = new AddConstantPrincipalTransformer.Builder(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .constant("name2") + .build(); + + client.apply(addConstantPrincipalTransformer); + client.apply(addConstantPrincipalTransformer2); + + assertTrue("Constant principal transformer should be created", + ops.exists(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_ADDRESS)); + assertTrue("Constant principal transformer should be created", + ops.exists(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_ADDRESS2)); + } + + @Test(expected = CommandFailedException.class) + public void addExistConstantPrincipalTransformerNotAllowed() throws Exception { + AddConstantPrincipalTransformer addConstantPrincipalTransformer + = new AddConstantPrincipalTransformer.Builder(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME) + .constant("name1") + .build(); + AddConstantPrincipalTransformer addConstantPrincipalTransformer2 + = new AddConstantPrincipalTransformer.Builder(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME) + .constant("name1") + .build(); + + client.apply(addConstantPrincipalTransformer); + assertTrue("Constant principal transformer should be created", + ops.exists(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_ADDRESS)); + + client.apply(addConstantPrincipalTransformer2); + fail("Constant principal transformer CreaperTestConstantPrincipalTransformer already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistConstantPrincipalTransformerAllowed() throws Exception { + AddConstantPrincipalTransformer addConstantPrincipalTransformer + = new AddConstantPrincipalTransformer.Builder(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME) + .constant("name1") + .build(); + AddConstantPrincipalTransformer addConstantPrincipalTransformer2 + = new AddConstantPrincipalTransformer.Builder(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME) + .constant("name2") + .replaceExisting() + .build(); + + client.apply(addConstantPrincipalTransformer); + assertTrue("Constant principal transformer should be created", + ops.exists(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_ADDRESS)); + checkConstantPrincipalTransformerConstant("name1"); + + client.apply(addConstantPrincipalTransformer2); + assertTrue("Constant principal transformer should be created", + ops.exists(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_ADDRESS)); + checkConstantPrincipalTransformerConstant("name2"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConstantPrincipalTransformer_nullName() throws Exception { + new AddConstantPrincipalTransformer.Builder(null) + .constant("name1") + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConstantPrincipalTransformer_emptyName() throws Exception { + new AddConstantPrincipalTransformer.Builder("") + .constant("name1") + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConstantPrincipalTransformer_nullConstant() throws Exception { + new AddConstantPrincipalTransformer.Builder(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME) + .constant(null) + .build(); + fail("Creating command with null constant should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConstantPrincipalTransformer_emptyConstant() throws Exception { + new AddConstantPrincipalTransformer.Builder(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME) + .constant("") + .build(); + fail("Creating command with empty constant should throw exception"); + } + + private void checkConstantPrincipalTransformerConstant(String expectedValue) throws IOException { + checkAttribute(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_ADDRESS, "constant", expectedValue); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantRealmMapperOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantRealmMapperOnlineTest.java new file mode 100644 index 00000000..f4346613 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantRealmMapperOnlineTest.java @@ -0,0 +1,134 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +@RunWith(Arquillian.class) +public class AddConstantRealmMapperOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_CONSTANT_REALM_MAPPER_NAME = "CreaperTestConstantRealmMapper"; + private static final Address TEST_CONSTANT_REALM_MAPPER_ADDRESS = SUBSYSTEM_ADDRESS + .and("constant-realm-mapper", TEST_CONSTANT_REALM_MAPPER_NAME); + private static final String TEST_CONSTANT_REALM_MAPPER_NAME2 = "CreaperTestConstantRealmMapper2"; + private static final Address TEST_CONSTANT_REALM_MAPPER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("constant-realm-mapper", TEST_CONSTANT_REALM_MAPPER_NAME2); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_CONSTANT_REALM_MAPPER_ADDRESS); + ops.removeIfExists(TEST_CONSTANT_REALM_MAPPER_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addConstantRealmMapper() throws Exception { + AddConstantRealmMapper addConstantRealmMapper + = new AddConstantRealmMapper.Builder(TEST_CONSTANT_REALM_MAPPER_NAME) + .realmName("someRealmName") + .build(); + + client.apply(addConstantRealmMapper); + + assertTrue("Constant realm mapper should be created", ops.exists(TEST_CONSTANT_REALM_MAPPER_ADDRESS)); + checkAttribute(TEST_CONSTANT_REALM_MAPPER_ADDRESS, "realm-name", "someRealmName"); + } + + @Test + public void addTwoConstantRealmMappers() throws Exception { + AddConstantRealmMapper addConstantRealmMapper + = new AddConstantRealmMapper.Builder(TEST_CONSTANT_REALM_MAPPER_NAME) + .realmName("someRealmName") + .build(); + AddConstantRealmMapper addConstantRealmMapper2 + = new AddConstantRealmMapper.Builder(TEST_CONSTANT_REALM_MAPPER_NAME2) + .realmName("someOtherRealmName") + .build(); + + client.apply(addConstantRealmMapper); + client.apply(addConstantRealmMapper2); + + assertTrue("Constant realm mapper should be created", ops.exists(TEST_CONSTANT_REALM_MAPPER_ADDRESS)); + assertTrue("Constant realm mapper should be created", ops.exists(TEST_CONSTANT_REALM_MAPPER_ADDRESS2)); + } + + @Test(expected = CommandFailedException.class) + public void addExistConstantRealmMapperNotAllowed() throws Exception { + AddConstantRealmMapper addConstantRealmMapper + = new AddConstantRealmMapper.Builder(TEST_CONSTANT_REALM_MAPPER_NAME) + .realmName("someRealmName") + .build(); + AddConstantRealmMapper addConstantRealmMapper2 + = new AddConstantRealmMapper.Builder(TEST_CONSTANT_REALM_MAPPER_NAME) + .realmName("someRealmName") + .build(); + + client.apply(addConstantRealmMapper); + assertTrue("Constant realm mapper should be created", ops.exists(TEST_CONSTANT_REALM_MAPPER_ADDRESS)); + + client.apply(addConstantRealmMapper2); + fail("Constant realm mapper CreaperTestConstantRealmMapper already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistConstantRealmMapperAllowed() throws Exception { + AddConstantRealmMapper addConstantRealmMapper + = new AddConstantRealmMapper.Builder(TEST_CONSTANT_REALM_MAPPER_NAME) + .realmName("someRealmName") + .build(); + AddConstantRealmMapper addConstantRealmMapper2 + = new AddConstantRealmMapper.Builder(TEST_CONSTANT_REALM_MAPPER_NAME) + .realmName("someOtherRealmName") + .replaceExisting() + .build(); + + client.apply(addConstantRealmMapper); + assertTrue("Constant realm mapper should be created", ops.exists(TEST_CONSTANT_REALM_MAPPER_ADDRESS)); + checkAttribute(TEST_CONSTANT_REALM_MAPPER_ADDRESS, "realm-name", "someRealmName"); + + client.apply(addConstantRealmMapper2); + assertTrue("Constant realm mapper should be created", ops.exists(TEST_CONSTANT_REALM_MAPPER_ADDRESS)); + checkAttribute(TEST_CONSTANT_REALM_MAPPER_ADDRESS, "realm-name", "someOtherRealmName"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConstantRealmMapper_nullName() throws Exception { + new AddConstantRealmMapper.Builder(null) + .realmName("someRealmName") + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConstantRealmMapper_emptyName() throws Exception { + new AddConstantRealmMapper.Builder("") + .realmName("someRealmName") + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConstantRealmMapper_nullRealmName() throws Exception { + new AddConstantRealmMapper.Builder(TEST_CONSTANT_REALM_MAPPER_NAME) + .realmName(null) + .build(); + fail("Creating command with null realm-name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConstantRealmMapper_emptyrealmName() throws Exception { + new AddConstantRealmMapper.Builder(TEST_CONSTANT_REALM_MAPPER_NAME) + .realmName("") + .build(); + fail("Creating command with empty realm-name should throw exception"); + } + +} + diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantRoleMapperOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantRoleMapperOnlineTest.java new file mode 100644 index 00000000..ff6d3103 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddConstantRoleMapperOnlineTest.java @@ -0,0 +1,127 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.Arrays; +import java.util.List; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddConstantRoleMapperOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_CONSTANT_ROLE_MAPPER_NAME = "CreaperTestConstantRoleMapper"; + private static final Address TEST_CONSTANT_ROLE_MAPPER_ADDRESS = SUBSYSTEM_ADDRESS + .and("constant-role-mapper", TEST_CONSTANT_ROLE_MAPPER_NAME); + private static final String TEST_CONSTANT_ROLE_MAPPER_NAME2 = "CreaperTestConstantRoleMapper2"; + private static final Address TEST_CONSTANT_ROLE_MAPPER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("constant-role-mapper", TEST_CONSTANT_ROLE_MAPPER_NAME2); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_CONSTANT_ROLE_MAPPER_ADDRESS); + ops.removeIfExists(TEST_CONSTANT_ROLE_MAPPER_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleConstantRoleMapper() throws Exception { + AddConstantRoleMapper addConstantRoleMapper = new AddConstantRoleMapper.Builder(TEST_CONSTANT_ROLE_MAPPER_NAME) + .addRoles("AnyRole") + .build(); + + client.apply(addConstantRoleMapper); + + assertTrue("Constant role mapper should be created", ops.exists(TEST_CONSTANT_ROLE_MAPPER_ADDRESS)); + } + + @Test + public void addTwoConstantRoleMappers() throws Exception { + AddConstantRoleMapper addConstantRoleMapper = new AddConstantRoleMapper.Builder(TEST_CONSTANT_ROLE_MAPPER_NAME) + .addRoles("AnyRole") + .build(); + + AddConstantRoleMapper addConstantRoleMapper2 + = new AddConstantRoleMapper.Builder(TEST_CONSTANT_ROLE_MAPPER_NAME2) + .addRoles("OtherRole", "Role#3") + .build(); + + client.apply(addConstantRoleMapper); + client.apply(addConstantRoleMapper2); + + assertTrue("Constant role mapper should be created", ops.exists(TEST_CONSTANT_ROLE_MAPPER_ADDRESS)); + assertTrue("Second constant role mapper should be created", ops.exists(TEST_CONSTANT_ROLE_MAPPER_ADDRESS2)); + + assertRoles(TEST_CONSTANT_ROLE_MAPPER_ADDRESS, "AnyRole"); + assertRoles(TEST_CONSTANT_ROLE_MAPPER_ADDRESS2, "OtherRole", "Role#3"); + + administration.reload(); + + assertRoles(TEST_CONSTANT_ROLE_MAPPER_ADDRESS, "AnyRole"); + assertRoles(TEST_CONSTANT_ROLE_MAPPER_ADDRESS2, "OtherRole", "Role#3"); + } + + @Test(expected = CommandFailedException.class) + public void addExistConstantRoleMapperNotAllowed() throws Exception { + AddConstantRoleMapper addConstantRoleMapper = new AddConstantRoleMapper.Builder(TEST_CONSTANT_ROLE_MAPPER_NAME) + .addRoles("AnyRole") + .build(); + + client.apply(addConstantRoleMapper); + assertTrue("Constant role mapper should be created", ops.exists(TEST_CONSTANT_ROLE_MAPPER_ADDRESS)); + client.apply(addConstantRoleMapper); + fail("Constant role mapper " + TEST_CONSTANT_ROLE_MAPPER_NAME + + " already exists in configuration, exception should be thrown"); + } + + public void addExistConstantRoleMapperAllowed() throws Exception { + AddConstantRoleMapper addConstantRoleMapper = new AddConstantRoleMapper.Builder(TEST_CONSTANT_ROLE_MAPPER_NAME) + .addRoles("AnyRole") + .build(); + + AddConstantRoleMapper addConstantRoleMapper2 = new AddConstantRoleMapper.Builder(TEST_CONSTANT_ROLE_MAPPER_NAME) + .addRoles("AnyRole2") + .replaceExisting() + .build(); + + client.apply(addConstantRoleMapper); + assertTrue("Constant role mapper should be created", ops.exists(TEST_CONSTANT_ROLE_MAPPER_ADDRESS)); + client.apply(addConstantRoleMapper2); + assertTrue("Constant role mapper should be created", ops.exists(TEST_CONSTANT_ROLE_MAPPER_ADDRESS)); + // check whether it was really rewritten + assertRoles(TEST_CONSTANT_ROLE_MAPPER_ADDRESS, "AnyRole2"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConstantRoleMapper_nullName() throws Exception { + new AddConstantRoleMapper.Builder(null); + fail("Creating command with null name should throw exception"); + } + + + @Test(expected = IllegalArgumentException.class) + public void addConstantRoleMapper_emptyName() throws Exception { + new AddConstantRoleMapper.Builder(""); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConstantRoleMapper_noRole() throws Exception { + new AddConstantRoleMapper.Builder(TEST_CONSTANT_ROLE_MAPPER_NAME).build(); + fail("Creating command with no role should throw exception"); + } + + private void assertRoles(Address address, String... expectedRoles) throws Exception { + List actualRoles = ops.readAttribute(address, "roles").stringListValue(); + assertEquals("Unexpected roles attribute value in " + address, Arrays.asList(expectedRoles), actualRoles); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPermissionMapperOfflineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPermissionMapperOfflineTest.java new file mode 100644 index 00000000..1921d4a2 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPermissionMapperOfflineTest.java @@ -0,0 +1,34 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractAddCustomOfflineTest; + + +@RunWith(Arquillian.class) +public class AddCustomPermissionMapperOfflineTest extends AbstractAddCustomOfflineTest { + + public String convertSubsystem(String subsystemString) { + return subsystemString.replaceAll(PARENT_TYPE, "mappers") + .replaceAll(CUSTOM_TYPE, "custom-permission-mapper") + .replaceAll(CUSTOM_NAME, getAddCustomName()) + .replaceAll(CLASS_NAME, getClassName()) + .replaceAll(MODULE_NAME, getModuleName()); + } + + public String getAddCustomName() { + return "customPermissionMapper"; + } + + public Object getBuilderObject(String name) { + return new AddCustomPermissionMapper.Builder(name); + } + + public String getModuleName() { + return "org.jboss.custompermissionmapperimpl"; + } + + public String getClassName() { + return "SomeCustomPermissionMapper"; + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPermissionMapperOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPermissionMapperOnlineTest.java new file mode 100644 index 00000000..4f6f299d --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPermissionMapperOnlineTest.java @@ -0,0 +1,64 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; + +@RunWith(Arquillian.class) +public class AddCustomPermissionMapperOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_ADD_CUSTOM_PERMISSION_MAPPER_NAME = "CreaperTestAddCustomPermissionMapper"; + + @Test(expected = IllegalArgumentException.class) + public void addCustomPermission_nullName() throws Exception { + new AddCustomPermissionMapper.Builder(null) + .module("someModule") + .className("someClassName"); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAddCustomPermissionMapper_emptyName() throws Exception { + new AddCustomPermissionMapper.Builder("") + .module("someModule") + .className("someClassName"); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomPermission_noClassName() throws Exception { + new AddCustomPermissionMapper.Builder(TEST_ADD_CUSTOM_PERMISSION_MAPPER_NAME) + .module("someModule") + .build(); + fail("Creating command with no classname should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomPermission_emptyClassName() throws Exception { + new AddCustomPermissionMapper.Builder(TEST_ADD_CUSTOM_PERMISSION_MAPPER_NAME) + .module("someModule") + .className("") + .build(); + fail("Creating command with empty classname should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomPermission_noModule() throws Exception { + new AddCustomPermissionMapper.Builder(TEST_ADD_CUSTOM_PERMISSION_MAPPER_NAME) + .className("someClassName") + .build(); + fail("Creating command with no module should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomPermission_emptyModule() throws Exception { + new AddCustomPermissionMapper.Builder(TEST_ADD_CUSTOM_PERMISSION_MAPPER_NAME) + .module("") + .className("someClassName") + .build(); + fail("Creating command with empty module should throw exception"); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalDecoderOfflineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalDecoderOfflineTest.java new file mode 100644 index 00000000..328c0e8c --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalDecoderOfflineTest.java @@ -0,0 +1,34 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractAddCustomOfflineTest; + + +@RunWith(Arquillian.class) +public class AddCustomPrincipalDecoderOfflineTest extends AbstractAddCustomOfflineTest { + + public String convertSubsystem(String subsystemString) { + return subsystemString.replaceAll(PARENT_TYPE, "mappers") + .replaceAll(CUSTOM_TYPE, "custom-principal-decoder") + .replaceAll(CUSTOM_NAME, getAddCustomName()) + .replaceAll(CLASS_NAME, getClassName()) + .replaceAll(MODULE_NAME, getModuleName()); + } + + public String getAddCustomName() { + return "customPrincipalDecoder"; + } + + public Object getBuilderObject(String name) { + return new AddCustomPrincipalDecoder.Builder(name); + } + + public String getModuleName() { + return "org.jboss.customprincipaldecoderimpl"; + } + + public String getClassName() { + return "SomeCustomPrincipalDecoder"; + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalDecoderOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalDecoderOnlineTest.java new file mode 100644 index 00000000..b0760cf6 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalDecoderOnlineTest.java @@ -0,0 +1,65 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; + +@RunWith(Arquillian.class) +public class AddCustomPrincipalDecoderOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_ADD_CUSTOM_PRINCIPAL_DECODER_NAME = "CreaperTestAddCustomPrincipalDecoder"; + + @Test(expected = IllegalArgumentException.class) + public void addCustomPrincipalDecoder_nullName() throws Exception { + new AddCustomPrincipalDecoder.Builder(null) + .module("someModule") + .className("someClassName"); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAddCustomPrincipalDecoder_emptyName() throws Exception { + new AddCustomPrincipalDecoder.Builder("") + .module("someModule") + .className("someClassName"); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomPrincipalDecoder_noClassName() throws Exception { + new AddCustomPrincipalDecoder.Builder(TEST_ADD_CUSTOM_PRINCIPAL_DECODER_NAME) + .module("someModule") + .build(); + fail("Creating command with no classname should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomPrincipalDecoder_emptyClassName() throws Exception { + new AddCustomPrincipalDecoder.Builder(TEST_ADD_CUSTOM_PRINCIPAL_DECODER_NAME) + .module("someModule") + .className("") + .build(); + fail("Creating command with empty classname should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomPrincipalDecoder_noModule() throws Exception { + new AddCustomPrincipalDecoder.Builder(TEST_ADD_CUSTOM_PRINCIPAL_DECODER_NAME) + .className("someClassName") + .build(); + fail("Creating command with no module should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomPrincipalDecoder_emptyModule() throws Exception { + new AddCustomPrincipalDecoder.Builder(TEST_ADD_CUSTOM_PRINCIPAL_DECODER_NAME) + .module("") + .className("someClassName") + .build(); + fail("Creating command with empty module should throw exception"); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalTransformerOfflineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalTransformerOfflineTest.java new file mode 100644 index 00000000..4ea570d8 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalTransformerOfflineTest.java @@ -0,0 +1,34 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractAddCustomOfflineTest; + + +@RunWith(Arquillian.class) +public class AddCustomPrincipalTransformerOfflineTest extends AbstractAddCustomOfflineTest { + + public String convertSubsystem(String subsystemString) { + return subsystemString.replaceAll(PARENT_TYPE, "mappers") + .replaceAll(CUSTOM_TYPE, "custom-principal-transformer") + .replaceAll(CUSTOM_NAME, getAddCustomName()) + .replaceAll(CLASS_NAME, getClassName()) + .replaceAll(MODULE_NAME, getModuleName()); + } + + public String getAddCustomName() { + return "customPrincipalTransformer"; + } + + public Object getBuilderObject(String name) { + return new AddCustomPrincipalTransformer.Builder(name); + } + + public String getModuleName() { + return "org.jboss.customprincipaltransformerimpl"; + } + + public String getClassName() { + return "SomeCustomPrincipalTransformer"; + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalTransformerOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalTransformerOnlineTest.java new file mode 100644 index 00000000..9e1bc28a --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomPrincipalTransformerOnlineTest.java @@ -0,0 +1,65 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; + +@RunWith(Arquillian.class) +public class AddCustomPrincipalTransformerOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_ADD_CUSTOM_PRINCIPAL_TRANSFORMER_NAME = "CreaperTestAddCustomPrincipalTransformer"; + + @Test(expected = IllegalArgumentException.class) + public void addCustomPrincipalTransformer_nullName() throws Exception { + new AddCustomPrincipalTransformer.Builder(null) + .module("someModule") + .className("someClassName"); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAddCustomPrincipalTransformer_emptyName() throws Exception { + new AddCustomPrincipalTransformer.Builder("") + .module("someModule") + .className("someClassName"); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomPrincipalTransformer_noClassName() throws Exception { + new AddCustomPrincipalTransformer.Builder(TEST_ADD_CUSTOM_PRINCIPAL_TRANSFORMER_NAME) + .module("someModule") + .build(); + fail("Creating command with no classname should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomPrincipalTransformer_emptyClassName() throws Exception { + new AddCustomPrincipalTransformer.Builder(TEST_ADD_CUSTOM_PRINCIPAL_TRANSFORMER_NAME) + .module("someModule") + .className("") + .build(); + fail("Creating command with empty classname should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomPrincipalTransformer_noModule() throws Exception { + new AddCustomPrincipalTransformer.Builder(TEST_ADD_CUSTOM_PRINCIPAL_TRANSFORMER_NAME) + .className("someClassName") + .build(); + fail("Creating command with no module should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomPrincipalTransformer_emptyModule() throws Exception { + new AddCustomPrincipalTransformer.Builder(TEST_ADD_CUSTOM_PRINCIPAL_TRANSFORMER_NAME) + .module("") + .className("someClassName") + .build(); + fail("Creating command with empty module should throw exception"); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRealmMapperOfflineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRealmMapperOfflineTest.java new file mode 100644 index 00000000..63d3945c --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRealmMapperOfflineTest.java @@ -0,0 +1,30 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.wildfly.extras.creaper.commands.elytron.AbstractAddCustomOfflineTest; + +public class AddCustomRealmMapperOfflineTest extends AbstractAddCustomOfflineTest { + + public String convertSubsystem(String subsystemString) { + return subsystemString.replaceAll(PARENT_TYPE, "mappers") + .replaceAll(CUSTOM_TYPE, "custom-realm-mapper") + .replaceAll(CUSTOM_NAME, getAddCustomName()) + .replaceAll(CLASS_NAME, getClassName()) + .replaceAll(MODULE_NAME, getModuleName()); + } + + public String getAddCustomName() { + return "customRealmMapper"; + } + + public Object getBuilderObject(String name) { + return new AddCustomRealmMapper.Builder(name); + } + + public String getModuleName() { + return "org.jboss.customrealmmapperimpl"; + } + + public String getClassName() { + return "SomeCustomRealmMapper"; + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRealmMapperOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRealmMapperOnlineTest.java new file mode 100644 index 00000000..010d237f --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRealmMapperOnlineTest.java @@ -0,0 +1,65 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; + +@RunWith(Arquillian.class) +public class AddCustomRealmMapperOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_ADD_CUSTOM_REALM_MAPPER_NAME = "CreaperTestAddCustomRealmMapper"; + + @Test(expected = IllegalArgumentException.class) + public void addCustomRealmMapper_nullName() throws Exception { + new AddCustomRealmMapper.Builder(null) + .module("someModule") + .className("someClassName"); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAddCustomRealmMapper_emptyName() throws Exception { + new AddCustomRealmMapper.Builder("") + .module("someModule") + .className("someClassName"); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomRealmMapper_noClassName() throws Exception { + new AddCustomRealmMapper.Builder(TEST_ADD_CUSTOM_REALM_MAPPER_NAME) + .module("someModule") + .build(); + fail("Creating command with no classname should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomRealmMapper_emptyClassName() throws Exception { + new AddCustomRealmMapper.Builder(TEST_ADD_CUSTOM_REALM_MAPPER_NAME) + .module("someModule") + .className("") + .build(); + fail("Creating command with empty classname should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomRealmMapper_noModule() throws Exception { + new AddCustomRealmMapper.Builder(TEST_ADD_CUSTOM_REALM_MAPPER_NAME) + .className("someClassName") + .build(); + fail("Creating command with no module should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomRealmMapper_emptyModule() throws Exception { + new AddCustomRealmMapper.Builder(TEST_ADD_CUSTOM_REALM_MAPPER_NAME) + .module("") + .className("someClassName") + .build(); + fail("Creating command with empty module should throw exception"); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleDecoderOfflineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleDecoderOfflineTest.java new file mode 100644 index 00000000..73130c90 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleDecoderOfflineTest.java @@ -0,0 +1,34 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractAddCustomOfflineTest; + + +@RunWith(Arquillian.class) +public class AddCustomRoleDecoderOfflineTest extends AbstractAddCustomOfflineTest { + + public String convertSubsystem(String subsystemString) { + return subsystemString.replaceAll(PARENT_TYPE, "mappers") + .replaceAll(CUSTOM_TYPE, "custom-role-decoder") + .replaceAll(CUSTOM_NAME, getAddCustomName()) + .replaceAll(CLASS_NAME, getClassName()) + .replaceAll(MODULE_NAME, getModuleName()); + } + + public String getAddCustomName() { + return "customRoleDecoder"; + } + + public Object getBuilderObject(String name) { + return new AddCustomRoleDecoder.Builder(name); + } + + public String getModuleName() { + return "org.jboss.customroledecoderimpl"; + } + + public String getClassName() { + return "SomeCustomRoleDecoder"; + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleDecoderOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleDecoderOnlineTest.java new file mode 100644 index 00000000..31a1e805 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleDecoderOnlineTest.java @@ -0,0 +1,64 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; + +@RunWith(Arquillian.class) +public class AddCustomRoleDecoderOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_ADD_CUSTOM_ROLE_DECODER_NAME = "CreaperTestAddCustomRoleDecoder"; + + @Test(expected = IllegalArgumentException.class) + public void addCustomRoleDecoder_nullName() throws Exception { + new AddCustomRoleDecoder.Builder(null) + .module("someModule") + .className("someClassName"); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAddCustomRoleDecoder_emptyName() throws Exception { + new AddCustomRoleDecoder.Builder("") + .module("someModule") + .className("someClassName"); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomRoleDecoder_noClassName() throws Exception { + new AddCustomRoleDecoder.Builder(TEST_ADD_CUSTOM_ROLE_DECODER_NAME) + .module("someModule") + .build(); + fail("Creating command with no classname should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomRoleDecoder_emptyClassName() throws Exception { + new AddCustomRoleDecoder.Builder(TEST_ADD_CUSTOM_ROLE_DECODER_NAME) + .module("someModule") + .className("") + .build(); + fail("Creating command with empty classname should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomRoleDecoder_noModule() throws Exception { + new AddCustomRoleDecoder.Builder(TEST_ADD_CUSTOM_ROLE_DECODER_NAME) + .className("someClassName") + .build(); + fail("Creating command with no module should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomRoleDecoder_emptyModule() throws Exception { + new AddCustomRoleDecoder.Builder(TEST_ADD_CUSTOM_ROLE_DECODER_NAME) + .module("") + .className("someClassName") + .build(); + fail("Creating command with empty module should throw exception"); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleMapperOfflineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleMapperOfflineTest.java new file mode 100644 index 00000000..800552a5 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleMapperOfflineTest.java @@ -0,0 +1,30 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import org.wildfly.extras.creaper.commands.elytron.AbstractAddCustomOfflineTest; + +public class AddCustomRoleMapperOfflineTest extends AbstractAddCustomOfflineTest { + + public String convertSubsystem(String subsystemString) { + return subsystemString.replaceAll(PARENT_TYPE, "mappers") + .replaceAll(CUSTOM_TYPE, "custom-role-mapper") + .replaceAll(CUSTOM_NAME, getAddCustomName()) + .replaceAll(CLASS_NAME, getClassName()) + .replaceAll(MODULE_NAME, getModuleName()); + } + + public String getAddCustomName() { + return "customRoleMapper"; + } + + public Object getBuilderObject(String name) { + return new AddCustomRoleMapper.Builder(name); + } + + public String getModuleName() { + return "org.jboss.customrolemapperimpl"; + } + + public String getClassName() { + return "SomeCustomRoleMapper"; + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleMapperOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleMapperOnlineTest.java new file mode 100644 index 00000000..355014c6 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddCustomRoleMapperOnlineTest.java @@ -0,0 +1,65 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; + +@RunWith(Arquillian.class) +public class AddCustomRoleMapperOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_ADD_CUSTOM_ROLE_MAPPER_NAME = "CreaperTestAddCustomRoleMapper"; + + @Test(expected = IllegalArgumentException.class) + public void addCustomRoleMapper_nullName() throws Exception { + new AddCustomRoleMapper.Builder(null) + .module("someModule") + .className("someClassName"); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAddCustomRoleMapper_emptyName() throws Exception { + new AddCustomRoleMapper.Builder("") + .module("someModule") + .className("someClassName"); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomRoleMapper_noClassName() throws Exception { + new AddCustomRoleMapper.Builder(TEST_ADD_CUSTOM_ROLE_MAPPER_NAME) + .module("someModule") + .build(); + fail("Creating command with no classname should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomRoleMapper_emptyClassName() throws Exception { + new AddCustomRoleMapper.Builder(TEST_ADD_CUSTOM_ROLE_MAPPER_NAME) + .module("someModule") + .className("") + .build(); + fail("Creating command with empty classname should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomRoleMapper_noModule() throws Exception { + new AddCustomRoleMapper.Builder(TEST_ADD_CUSTOM_ROLE_MAPPER_NAME) + .className("someClassName") + .build(); + fail("Creating command with no module should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomRoleMapper_emptyModule() throws Exception { + new AddCustomRoleMapper.Builder(TEST_ADD_CUSTOM_ROLE_MAPPER_NAME) + .module("") + .className("someClassName") + .build(); + fail("Creating command with empty module should throw exception"); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddLogicalPermissionMapperOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddLogicalPermissionMapperOnlineTest.java new file mode 100644 index 00000000..88a988c8 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddLogicalPermissionMapperOnlineTest.java @@ -0,0 +1,191 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddLogicalPermissionMapperOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_LOGICAL_PERMISSION_MAPPER_NAME = "CreaperTestLogicalPermissionMapper"; + private static final Address TEST_LOGICAL_PERMISSION_MAPPER_ADDRESS = SUBSYSTEM_ADDRESS + .and("logical-permission-mapper", TEST_LOGICAL_PERMISSION_MAPPER_NAME); + private static final String TEST_LOGICAL_PERMISSION_MAPPER_NAME2 = "CreaperTestLogicalPermissionMapper2"; + private static final Address TEST_LOGICAL_PERMISSION_MAPPER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("logical-permission-mapper", TEST_LOGICAL_PERMISSION_MAPPER_NAME2); + + private static final String TEST_SIMPLE_PERMISSION_MAPPER_NAME = "CreaperTestSimplePermissionMapper"; + private static final Address TEST_SIMPLE_PERMISSION_MAPPER_ADDRESS = SUBSYSTEM_ADDRESS + .and("simple-permission-mapper", TEST_SIMPLE_PERMISSION_MAPPER_NAME); + private final AddSimplePermissionMapper addSimplePermissionMapper + = new AddSimplePermissionMapper.Builder(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .addPermissionMappings(new AddSimplePermissionMapper.PermissionMappingBuilder() + .addPermissions(new AddSimplePermissionMapper.PermissionBuilder() + .className("org.wildfly.security.auth.permission.LoginPermission") + .build()) + .build()) + .build(); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_LOGICAL_PERMISSION_MAPPER_ADDRESS); + ops.removeIfExists(TEST_LOGICAL_PERMISSION_MAPPER_ADDRESS2); + ops.removeIfExists(TEST_SIMPLE_PERMISSION_MAPPER_ADDRESS); + administration.reloadIfRequired(); + } + + @Test + public void addFullLogicalPermissionMapper() throws Exception { + client.apply(addSimplePermissionMapper); + + AddLogicalPermissionMapper addLogicalPermissionMapper + = new AddLogicalPermissionMapper.Builder(TEST_LOGICAL_PERMISSION_MAPPER_NAME) + .logicalOperation(AddLogicalPermissionMapper.LogicalOperation.UNLESS) + .left(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .right(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .build(); + + client.apply(addLogicalPermissionMapper); + + assertTrue("Logical permission mapper should be created", ops.exists(TEST_LOGICAL_PERMISSION_MAPPER_ADDRESS)); + + checkAttribute(TEST_LOGICAL_PERMISSION_MAPPER_ADDRESS, "logical-operation", "unless"); + checkAttribute(TEST_LOGICAL_PERMISSION_MAPPER_ADDRESS, "left", TEST_SIMPLE_PERMISSION_MAPPER_NAME); + checkAttribute(TEST_LOGICAL_PERMISSION_MAPPER_ADDRESS, "right", TEST_SIMPLE_PERMISSION_MAPPER_NAME); + } + + @Test + public void addTwoLogicalPermissionMappers() throws Exception { + client.apply(addSimplePermissionMapper); + + AddLogicalPermissionMapper addLogicalPermissionMapper + = new AddLogicalPermissionMapper.Builder(TEST_LOGICAL_PERMISSION_MAPPER_NAME) + .logicalOperation(AddLogicalPermissionMapper.LogicalOperation.OR) + .left(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .right(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .build(); + + AddLogicalPermissionMapper addLogicalPermissionMapper2 + = new AddLogicalPermissionMapper.Builder(TEST_LOGICAL_PERMISSION_MAPPER_NAME2) + .logicalOperation(AddLogicalPermissionMapper.LogicalOperation.AND) + .left(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .right(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .build(); + + client.apply(addLogicalPermissionMapper); + client.apply(addLogicalPermissionMapper2); + + assertTrue("Logical permission mapper should be created", ops.exists(TEST_LOGICAL_PERMISSION_MAPPER_ADDRESS)); + assertTrue("Second logical permission mapper should be created", + ops.exists(TEST_LOGICAL_PERMISSION_MAPPER_ADDRESS2)); + } + + @Test(expected = CommandFailedException.class) + public void addExistLogicalPermissionMapperNotAllowed() throws Exception { + client.apply(addSimplePermissionMapper); + + AddLogicalPermissionMapper addLogicalPermissionMapper + = new AddLogicalPermissionMapper.Builder(TEST_LOGICAL_PERMISSION_MAPPER_NAME) + .logicalOperation(AddLogicalPermissionMapper.LogicalOperation.OR) + .left(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .right(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .build(); + + AddLogicalPermissionMapper addLogicalPermissionMapper2 + = new AddLogicalPermissionMapper.Builder(TEST_LOGICAL_PERMISSION_MAPPER_NAME) + .logicalOperation(AddLogicalPermissionMapper.LogicalOperation.AND) + .left(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .right(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .build(); + + client.apply(addLogicalPermissionMapper); + assertTrue("Logical permission mapper should be created", ops.exists(TEST_LOGICAL_PERMISSION_MAPPER_ADDRESS)); + client.apply(addLogicalPermissionMapper2); + fail("Logical permission mapper CreaperTestLogicalPermissionMapper already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistLogicalPermissionMapperAllowed() throws Exception { + client.apply(addSimplePermissionMapper); + + AddLogicalPermissionMapper addLogicalPermissionMapper + = new AddLogicalPermissionMapper.Builder(TEST_LOGICAL_PERMISSION_MAPPER_NAME) + .logicalOperation(AddLogicalPermissionMapper.LogicalOperation.OR) + .left(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .right(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .build(); + + AddLogicalPermissionMapper addLogicalPermissionMapper2 + = new AddLogicalPermissionMapper.Builder(TEST_LOGICAL_PERMISSION_MAPPER_NAME) + .logicalOperation(AddLogicalPermissionMapper.LogicalOperation.AND) + .left(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .right(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .replaceExisting() + .build(); + + client.apply(addLogicalPermissionMapper); + assertTrue("Logical permission mapper should be created", ops.exists(TEST_LOGICAL_PERMISSION_MAPPER_ADDRESS)); + client.apply(addLogicalPermissionMapper2); + assertTrue("Logical permission mapper should be created", ops.exists(TEST_LOGICAL_PERMISSION_MAPPER_ADDRESS)); + // check whether it was really rewritten + checkAttribute(TEST_LOGICAL_PERMISSION_MAPPER_ADDRESS, "logical-operation", "and"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLogicalPermissionMapper_nullName() throws Exception { + new AddLogicalPermissionMapper.Builder(null) + .logicalOperation(AddLogicalPermissionMapper.LogicalOperation.OR) + .left(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .right(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLogicalPermissionMapper_emptyName() throws Exception { + new AddLogicalPermissionMapper.Builder("") + .logicalOperation(AddLogicalPermissionMapper.LogicalOperation.OR) + .left(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .right(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLogicalPermissionMapper_nullLogicalOperation() throws Exception { + new AddLogicalPermissionMapper.Builder(TEST_LOGICAL_PERMISSION_MAPPER_NAME) + .logicalOperation(null) + .left(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .right(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .build(); + fail("Creating command with null logical operation should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLogicalPermissionMapper_nullLeft() throws Exception { + new AddLogicalPermissionMapper.Builder(TEST_LOGICAL_PERMISSION_MAPPER_NAME) + .logicalOperation(AddLogicalPermissionMapper.LogicalOperation.OR) + .left(null) + .right(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .build(); + fail("Creating command with null left should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLogicalPermissionMapper_nullRight() throws Exception { + new AddLogicalPermissionMapper.Builder(TEST_LOGICAL_PERMISSION_MAPPER_NAME) + .logicalOperation(AddLogicalPermissionMapper.LogicalOperation.OR) + .left(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .right(null) + .build(); + fail("Creating command with null right should throw exception"); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddLogicalRoleMapperOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddLogicalRoleMapperOnlineTest.java new file mode 100644 index 00000000..cbc50acd --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddLogicalRoleMapperOnlineTest.java @@ -0,0 +1,144 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddLogicalRoleMapperOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_LOGICAL_ROLE_MAPPER_NAME = "CreaperTestLogicalRoleMapper"; + private static final Address TEST_LOGICAL_ROLE_MAPPER_ADDRESS = SUBSYSTEM_ADDRESS + .and("logical-role-mapper", TEST_LOGICAL_ROLE_MAPPER_NAME); + private static final String TEST_LOGICAL_ROLE_MAPPER_NAME2 = "CreaperTestLogicalRoleMapper2"; + private static final Address TEST_LOGICAL_ROLE_MAPPER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("logical-role-mapper", TEST_LOGICAL_ROLE_MAPPER_NAME2); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_LOGICAL_ROLE_MAPPER_ADDRESS); + ops.removeIfExists(TEST_LOGICAL_ROLE_MAPPER_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addLogicalRoleMapper() throws Exception { + AddLogicalRoleMapper addLogicalRoleMapper = new AddLogicalRoleMapper.Builder(TEST_LOGICAL_ROLE_MAPPER_NAME) + .logicalOperation(AddLogicalRoleMapper.LogicalOperation.OR) + .build(); + + client.apply(addLogicalRoleMapper); + + assertTrue("Logical role mapper should be created", ops.exists(TEST_LOGICAL_ROLE_MAPPER_ADDRESS)); + } + + @Test + public void addLogicalRoleMappers() throws Exception { + AddLogicalRoleMapper addLogicalRoleMapper = new AddLogicalRoleMapper.Builder(TEST_LOGICAL_ROLE_MAPPER_NAME) + .logicalOperation(AddLogicalRoleMapper.LogicalOperation.OR) + .build(); + + AddLogicalRoleMapper addLogicalRoleMapper2 = new AddLogicalRoleMapper.Builder(TEST_LOGICAL_ROLE_MAPPER_NAME2) + .logicalOperation(AddLogicalRoleMapper.LogicalOperation.OR) + .build(); + + client.apply(addLogicalRoleMapper); + client.apply(addLogicalRoleMapper2); + + assertTrue("Logical role mapper should be created", ops.exists(TEST_LOGICAL_ROLE_MAPPER_ADDRESS)); + assertTrue("Second logical role mapper should be created", ops.exists(TEST_LOGICAL_ROLE_MAPPER_ADDRESS2)); + } + + @Test + public void addFullLogicalRoleMapper() throws Exception { + AddConstantRoleMapper addConstantRoleMapper = new AddConstantRoleMapper.Builder("creaper-contant-role-mapper-1") + .addRoles("AnyRole1") + .build(); + AddConstantRoleMapper addConstantRoleMapper2 = new AddConstantRoleMapper.Builder("creaper-contant-role-mapper-2") + .addRoles("AnyRole2") + .build(); + client.apply(addConstantRoleMapper); + client.apply(addConstantRoleMapper2); + + AddLogicalRoleMapper addLogicalRoleMapper = new AddLogicalRoleMapper.Builder(TEST_LOGICAL_ROLE_MAPPER_NAME) + .logicalOperation(AddLogicalRoleMapper.LogicalOperation.OR) + .left("creaper-contant-role-mapper-1") + .right("creaper-contant-role-mapper-2") + .build(); + + client.apply(addLogicalRoleMapper); + + assertTrue("Logical role mapper should be created", ops.exists(TEST_LOGICAL_ROLE_MAPPER_ADDRESS)); + + checkAttribute(TEST_LOGICAL_ROLE_MAPPER_ADDRESS, "logical-operation", "or"); + checkAttribute(TEST_LOGICAL_ROLE_MAPPER_ADDRESS, "left", "creaper-contant-role-mapper-1"); + checkAttribute(TEST_LOGICAL_ROLE_MAPPER_ADDRESS, "right", "creaper-contant-role-mapper-2"); + } + + @Test(expected = CommandFailedException.class) + public void addLogicalRoleMapperNotAllowed() throws Exception { + AddLogicalRoleMapper addLogicalRoleMapper = new AddLogicalRoleMapper.Builder(TEST_LOGICAL_ROLE_MAPPER_NAME) + .logicalOperation(AddLogicalRoleMapper.LogicalOperation.OR) + .build(); + + AddLogicalRoleMapper addLogicalRoleMapper2 = new AddLogicalRoleMapper.Builder(TEST_LOGICAL_ROLE_MAPPER_NAME) + .logicalOperation(AddLogicalRoleMapper.LogicalOperation.AND) + .build(); + + client.apply(addLogicalRoleMapper); + assertTrue("Logical role mapper should be created", ops.exists(TEST_LOGICAL_ROLE_MAPPER_ADDRESS)); + client.apply(addLogicalRoleMapper2); + fail("Logical role mapper CreaperTestLogicalRoleMapper already exists in configuration, exception should be thrown"); + } + + @Test + public void addLogicalRoleMapperAllowed() throws Exception { + AddLogicalRoleMapper addLogicalRoleMapper = new AddLogicalRoleMapper.Builder(TEST_LOGICAL_ROLE_MAPPER_NAME) + .logicalOperation(AddLogicalRoleMapper.LogicalOperation.OR) + .build(); + + AddLogicalRoleMapper addLogicalRoleMapper2 = new AddLogicalRoleMapper.Builder(TEST_LOGICAL_ROLE_MAPPER_NAME) + .logicalOperation(AddLogicalRoleMapper.LogicalOperation.AND) + .replaceExisting() + .build(); + + client.apply(addLogicalRoleMapper); + assertTrue("Logical role mapper should be created", ops.exists(TEST_LOGICAL_ROLE_MAPPER_ADDRESS)); + client.apply(addLogicalRoleMapper2); + assertTrue("Logical role mapper should be created", ops.exists(TEST_LOGICAL_ROLE_MAPPER_ADDRESS)); + // check whether it was really rewritten + checkAttribute(TEST_LOGICAL_ROLE_MAPPER_ADDRESS, "logical-operation", "and"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLogicalRoleMapper_nullName() throws Exception { + new AddLogicalRoleMapper.Builder(null) + .logicalOperation(AddLogicalRoleMapper.LogicalOperation.OR) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLogicalRoleMapper_emptyName() throws Exception { + new AddLogicalRoleMapper.Builder("") + .logicalOperation(AddLogicalRoleMapper.LogicalOperation.OR) + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLogicalRoleMapper_nullLogicalOperation() throws Exception { + new AddLogicalRoleMapper.Builder(TEST_LOGICAL_ROLE_MAPPER_NAME) + .logicalOperation(null) + .build(); + fail("Creating command with null logical operation should throw exception"); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddMappedRegexRealmMapperOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddMappedRegexRealmMapperOnlineTest.java new file mode 100644 index 00000000..46b15cb7 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddMappedRegexRealmMapperOnlineTest.java @@ -0,0 +1,214 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddMappedRegexRealmMapperOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_MAPPED_REGEX_REALM_MAPPER_NAME = "CreaperTestMappedRegexRealmMapper"; + private static final Address TEST_MAPPED_REGEX_REALM_MAPPER_ADDRESS = SUBSYSTEM_ADDRESS + .and("mapped-regex-realm-mapper", TEST_MAPPED_REGEX_REALM_MAPPER_NAME); + private static final String TEST_MAPPED_REGEX_REALM_MAPPER_NAME2 = "CreaperTestMappedRegexRealmMapper2"; + private static final Address TEST_MAPPED_REGEX_REALM_MAPPER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("mapped-regex-realm-mapper", TEST_MAPPED_REGEX_REALM_MAPPER_NAME2); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_MAPPED_REGEX_REALM_MAPPER_ADDRESS); + ops.removeIfExists(TEST_MAPPED_REGEX_REALM_MAPPER_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleMappedRegexRealmMapper() throws Exception { + AddMappedRegexRealmMapper addMappedRegexRealmMapper + = new AddMappedRegexRealmMapper.Builder(TEST_MAPPED_REGEX_REALM_MAPPER_NAME) + .pattern("(somePattern)") + .addRealmMappings(new AddMappedRegexRealmMapper.RealmMapping("someFrom", "someTo")) + .build(); + + client.apply(addMappedRegexRealmMapper); + + assertTrue("Mapped regex realm mapper should be created", ops.exists(TEST_MAPPED_REGEX_REALM_MAPPER_ADDRESS)); + } + + @Test + public void addTwoMappedRegexRealmMappers() throws Exception { + AddMappedRegexRealmMapper addMappedRegexRealmMapper + = new AddMappedRegexRealmMapper.Builder(TEST_MAPPED_REGEX_REALM_MAPPER_NAME) + .pattern("(somePattern)") + .addRealmMappings(new AddMappedRegexRealmMapper.RealmMapping("someFrom", "someTo")) + .build(); + AddMappedRegexRealmMapper addMappedRegexRealmMapper2 + = new AddMappedRegexRealmMapper.Builder(TEST_MAPPED_REGEX_REALM_MAPPER_NAME2) + .pattern("(somePattern)") + .addRealmMappings(new AddMappedRegexRealmMapper.RealmMapping("someFrom", "someTo")) + .build(); + + client.apply(addMappedRegexRealmMapper); + client.apply(addMappedRegexRealmMapper2); + + assertTrue("Mapped regex realm mapper should be created", ops.exists(TEST_MAPPED_REGEX_REALM_MAPPER_ADDRESS)); + assertTrue("Mapped regex realm mapper should be created", ops.exists(TEST_MAPPED_REGEX_REALM_MAPPER_ADDRESS2)); + } + + @Test + public void addFullMappedRegexRealmMapper() throws Exception { + AddMappedRegexRealmMapper addMappedRegexRealmMapper2 + = new AddMappedRegexRealmMapper.Builder(TEST_MAPPED_REGEX_REALM_MAPPER_NAME2) + .pattern("(somePattern2)") + .addRealmMappings(new AddMappedRegexRealmMapper.RealmMapping("someFrom", "someTo")) + .build(); + client.apply(addMappedRegexRealmMapper2); + + AddMappedRegexRealmMapper addMappedRegexRealmMapper + = new AddMappedRegexRealmMapper.Builder(TEST_MAPPED_REGEX_REALM_MAPPER_NAME) + .pattern("(somePattern)") + .delegateRealmMapper(TEST_MAPPED_REGEX_REALM_MAPPER_NAME2) + .addRealmMappings(new AddMappedRegexRealmMapper.RealmMapping("someFrom1", "someTo1"), + new AddMappedRegexRealmMapper.RealmMapping("someFrom2", "someTo2")) + .build(); + + client.apply(addMappedRegexRealmMapper); + + assertTrue("Mapped regex realm mapper should be created", ops.exists(TEST_MAPPED_REGEX_REALM_MAPPER_ADDRESS)); + + checkAttribute(TEST_MAPPED_REGEX_REALM_MAPPER_ADDRESS, "pattern", "(somePattern)"); + checkAttribute(TEST_MAPPED_REGEX_REALM_MAPPER_ADDRESS, "delegate-realm-mapper", + TEST_MAPPED_REGEX_REALM_MAPPER_NAME2); + checkAttribute(TEST_MAPPED_REGEX_REALM_MAPPER_ADDRESS, "realm-map.someFrom1", "someTo1"); + checkAttribute(TEST_MAPPED_REGEX_REALM_MAPPER_ADDRESS, "realm-map.someFrom2", "someTo2"); + } + + @Test(expected = CommandFailedException.class) + public void addExistMappedRegexRealmMapperNotAllowed() throws Exception { + AddMappedRegexRealmMapper addMappedRegexRealmMapper + = new AddMappedRegexRealmMapper.Builder(TEST_MAPPED_REGEX_REALM_MAPPER_NAME) + .pattern("(somePattern)") + .addRealmMappings(new AddMappedRegexRealmMapper.RealmMapping("someFrom", "someTo")) + .build(); + + AddMappedRegexRealmMapper addMappedRegexRealmMapper2 + = new AddMappedRegexRealmMapper.Builder(TEST_MAPPED_REGEX_REALM_MAPPER_NAME) + .pattern("(somePattern2)") + .addRealmMappings(new AddMappedRegexRealmMapper.RealmMapping("someFrom", "someTo")) + .build(); + + client.apply(addMappedRegexRealmMapper); + assertTrue("Mapped regex realm mapper should be created", ops.exists(TEST_MAPPED_REGEX_REALM_MAPPER_ADDRESS)); + client.apply(addMappedRegexRealmMapper2); + fail("Mapped regex realm mapper CreaperTestMappedRegexRealmMapper already exists in configuration, exception should be thrown"); + } + + public void addExistMappedRegexRealmMapperAllowed() throws Exception { + AddMappedRegexRealmMapper addMappedRegexRealmMapper + = new AddMappedRegexRealmMapper.Builder(TEST_MAPPED_REGEX_REALM_MAPPER_NAME) + .pattern("(somePattern)") + .addRealmMappings(new AddMappedRegexRealmMapper.RealmMapping("someFrom", "someTo")) + .build(); + + AddMappedRegexRealmMapper addMappedRegexRealmMapper2 + = new AddMappedRegexRealmMapper.Builder(TEST_MAPPED_REGEX_REALM_MAPPER_NAME) + .pattern("(somePattern2)") + .addRealmMappings(new AddMappedRegexRealmMapper.RealmMapping("someFrom", "someTo")) + .replaceExisting() + .build(); + + client.apply(addMappedRegexRealmMapper); + assertTrue("Mapped regex realm mapper should be created", ops.exists(TEST_MAPPED_REGEX_REALM_MAPPER_ADDRESS)); + client.apply(addMappedRegexRealmMapper2); + assertTrue("Mapped regex realm mapper should be created", ops.exists(TEST_MAPPED_REGEX_REALM_MAPPER_ADDRESS)); + // check whether it was really rewritten + checkAttribute(TEST_MAPPED_REGEX_REALM_MAPPER_ADDRESS, "pattern", "(somePattern2)"); + } + + @Test(expected = IllegalArgumentException.class) + public void addMappedRegexRealmMapper_nullName() throws Exception { + new AddMappedRegexRealmMapper.Builder(null) + .pattern("(somePattern)") + .addRealmMappings(new AddMappedRegexRealmMapper.RealmMapping("someFrom", "someTo")) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addMappedRegexRealmMapper_emptyName() throws Exception { + new AddMappedRegexRealmMapper.Builder("") + .pattern("(somePattern)") + .addRealmMappings(new AddMappedRegexRealmMapper.RealmMapping("someFrom", "someTo")) + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addMappedRegexRealmMapper_nullPattern() throws Exception { + new AddMappedRegexRealmMapper.Builder(TEST_MAPPED_REGEX_REALM_MAPPER_NAME) + .pattern(null) + .addRealmMappings(new AddMappedRegexRealmMapper.RealmMapping("someFrom", "someTo")) + .build(); + fail("Creating command with null pattern should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addMappedRegexRealmMapper_emptyPattern() throws Exception { + new AddMappedRegexRealmMapper.Builder(TEST_MAPPED_REGEX_REALM_MAPPER_NAME) + .pattern("") + .addRealmMappings(new AddMappedRegexRealmMapper.RealmMapping("someFrom", "someTo")) + .build(); + fail("Creating command with empty pattern should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addMappedRegexRealmMapper_nullRealmMapping() throws Exception { + new AddMappedRegexRealmMapper.Builder(TEST_MAPPED_REGEX_REALM_MAPPER_NAME) + .pattern("(somePattern)") + .addRealmMappings(null) + .build(); + fail("Creating command with null realm mapping should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addMappedRegexRealmMapper_noRealmMapping() throws Exception { + new AddMappedRegexRealmMapper.Builder(TEST_MAPPED_REGEX_REALM_MAPPER_NAME) + .pattern("(somePattern)") + .build(); + fail("Creating command with no realm mapping should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addMappedRegexRealmMapper_emptyRealmMapping() throws Exception { + new AddMappedRegexRealmMapper.Builder(TEST_MAPPED_REGEX_REALM_MAPPER_NAME) + .pattern("(somePattern)") + .addRealmMappings() + .build(); + fail("Creating command with empty realm mapping should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addMappedRegexRealmMapper_nullFrom() throws Exception { + new AddMappedRegexRealmMapper.Builder(TEST_MAPPED_REGEX_REALM_MAPPER_NAME) + .pattern("(somePattern)") + .addRealmMappings(new AddMappedRegexRealmMapper.RealmMapping(null, "someTo")) + .build(); + fail("Creating command with null realm mapping 'from' should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addMappedRegexRealmMapper_nullTo() throws Exception { + new AddMappedRegexRealmMapper.Builder(TEST_MAPPED_REGEX_REALM_MAPPER_NAME) + .pattern("(somePattern)") + .addRealmMappings(new AddMappedRegexRealmMapper.RealmMapping("someFrom", null)) + .build(); + fail("Creating command with null realm mapping 'to' should throw exception"); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddRegexPrincipalTransformerOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddRegexPrincipalTransformerOnlineTest.java new file mode 100644 index 00000000..0dcb02e8 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddRegexPrincipalTransformerOnlineTest.java @@ -0,0 +1,166 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import java.io.IOException; +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +@RunWith(Arquillian.class) +public class AddRegexPrincipalTransformerOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_REGEX_PRINCIPAL_TRANSFORMER_NAME = "CreaperTestRegexPrincipalTransformer"; + private static final Address TEST_REGEX_PRINCIPAL_TRANSFORMER_ADDRESS = SUBSYSTEM_ADDRESS + .and("regex-principal-transformer", TEST_REGEX_PRINCIPAL_TRANSFORMER_NAME); + private static final String TEST_REGEX_PRINCIPAL_TRANSFORMER_NAME2 = "CreaperTestRegexPrincipalTransformer2"; + private static final Address TEST_REGEX_PRINCIPAL_TRANSFORMER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("regex-principal-transformer", TEST_REGEX_PRINCIPAL_TRANSFORMER_NAME2); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_REGEX_PRINCIPAL_TRANSFORMER_ADDRESS); + ops.removeIfExists(TEST_REGEX_PRINCIPAL_TRANSFORMER_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addRegexPrincipalTransformer() throws Exception { + AddRegexPrincipalTransformer addRegexPrincipalTransformer + = new AddRegexPrincipalTransformer.Builder(TEST_REGEX_PRINCIPAL_TRANSFORMER_NAME) + .pattern("test-pattern") + .replacement("test-replacement") + .replaceAll(true) + .build(); + + client.apply(addRegexPrincipalTransformer); + + assertTrue("Regex principal transformer should be created", + ops.exists(TEST_REGEX_PRINCIPAL_TRANSFORMER_ADDRESS)); + checkRegexPrincipalTransformerAttribute("pattern", "test-pattern"); + checkRegexPrincipalTransformerAttribute("replacement", "test-replacement"); + checkRegexPrincipalTransformerAttribute("replace-all", "true"); + } + + @Test + public void addTwoRegexPrincipalTransformers() throws Exception { + AddRegexPrincipalTransformer addRegexPrincipalTransformer + = new AddRegexPrincipalTransformer.Builder(TEST_REGEX_PRINCIPAL_TRANSFORMER_NAME) + .pattern("test-pattern") + .replacement("test-replacement") + .build(); + AddRegexPrincipalTransformer addRegexPrincipalTransformer2 + = new AddRegexPrincipalTransformer.Builder(TEST_REGEX_PRINCIPAL_TRANSFORMER_NAME2) + .pattern("test-pattern2") + .replacement("test-replacement2") + .build(); + + client.apply(addRegexPrincipalTransformer); + client.apply(addRegexPrincipalTransformer2); + + assertTrue("Regex principal transformer should be created", + ops.exists(TEST_REGEX_PRINCIPAL_TRANSFORMER_ADDRESS)); + assertTrue("Regex principal transformer should be created", + ops.exists(TEST_REGEX_PRINCIPAL_TRANSFORMER_ADDRESS2)); + } + + @Test(expected = CommandFailedException.class) + public void addExistRegexPrincipalTransformerNotAllowed() throws Exception { + AddRegexPrincipalTransformer addRegexPrincipalTransformer + = new AddRegexPrincipalTransformer.Builder(TEST_REGEX_PRINCIPAL_TRANSFORMER_NAME) + .pattern("test-pattern") + .replacement("test-replacement") + .build(); + AddRegexPrincipalTransformer addRegexPrincipalTransformer2 + = new AddRegexPrincipalTransformer.Builder(TEST_REGEX_PRINCIPAL_TRANSFORMER_NAME) + .pattern("test-pattern2") + .replacement("test-replacement2") + .build(); + + client.apply(addRegexPrincipalTransformer); + assertTrue("Regex principal transformer should be created", + ops.exists(TEST_REGEX_PRINCIPAL_TRANSFORMER_ADDRESS)); + + client.apply(addRegexPrincipalTransformer2); + fail("Regex principal transformer CreaperTestRegexPrincipalTransformer already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistRegexPrincipalTransformerAllowed() throws Exception { + AddRegexPrincipalTransformer addRegexPrincipalTransformer + = new AddRegexPrincipalTransformer.Builder(TEST_REGEX_PRINCIPAL_TRANSFORMER_NAME) + .pattern("test-pattern") + .replacement("test-replacement") + .build(); + AddRegexPrincipalTransformer addRegexPrincipalTransformer2 + = new AddRegexPrincipalTransformer.Builder(TEST_REGEX_PRINCIPAL_TRANSFORMER_NAME) + .pattern("test-pattern2") + .replacement("test-replacement2") + .replaceExisting() + .build(); + + client.apply(addRegexPrincipalTransformer); + assertTrue("Regex principal transformer should be created", + ops.exists(TEST_REGEX_PRINCIPAL_TRANSFORMER_ADDRESS)); + + client.apply(addRegexPrincipalTransformer2); + assertTrue("Regex principal transformer should be created", + ops.exists(TEST_REGEX_PRINCIPAL_TRANSFORMER_ADDRESS)); + checkRegexPrincipalTransformerAttribute("pattern", "test-pattern2"); + checkRegexPrincipalTransformerAttribute("replacement", "test-replacement2"); + } + + @Test(expected = IllegalArgumentException.class) + public void addRegexPrincipalTransformer_nullName() throws Exception { + new AddRegexPrincipalTransformer.Builder(null) + .pattern("test-pattern") + .replacement("test-replacement") + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addRegexPrincipalTransformer_emptyName() throws Exception { + new AddRegexPrincipalTransformer.Builder("") + .pattern("test-pattern") + .replacement("test-replacement") + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addRegexPrincipalTransformer_nullPattern() throws Exception { + new AddRegexPrincipalTransformer.Builder(TEST_REGEX_PRINCIPAL_TRANSFORMER_NAME) + .pattern(null) + .replacement("test-replacement") + .build(); + fail("Creating command with null pattern should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addRegexPrincipalTransformer_emptyPattern() throws Exception { + new AddRegexPrincipalTransformer.Builder(TEST_REGEX_PRINCIPAL_TRANSFORMER_NAME) + .pattern("") + .replacement("test-replacement") + .build(); + fail("Creating command with empty pattern should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addRegexPrincipalTransformer_nullReplacement() throws Exception { + new AddRegexPrincipalTransformer.Builder(TEST_REGEX_PRINCIPAL_TRANSFORMER_NAME) + .pattern("test-pattern") + .replacement(null) + .build(); + fail("Creating command with null replacement should throw exception"); + } + + private void checkRegexPrincipalTransformerAttribute(String attr, String expected) throws IOException { + checkAttribute(TEST_REGEX_PRINCIPAL_TRANSFORMER_ADDRESS, attr, expected); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddRegexValidatingPrincipalTransformerOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddRegexValidatingPrincipalTransformerOnlineTest.java new file mode 100644 index 00000000..ce08e4e8 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddRegexValidatingPrincipalTransformerOnlineTest.java @@ -0,0 +1,157 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import java.io.IOException; +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +@RunWith(Arquillian.class) +public class AddRegexValidatingPrincipalTransformerOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_REGEX_VALIDATING_PRINCIPAL_TRANSFORMER_NAME = "CreaperTestRegexValidatingPrincipalTransformer"; + private static final Address TEST_REGEX_VALIDATING_PRINCIPAL_TRANSFORMER_ADDRESS = SUBSYSTEM_ADDRESS + .and("regex-validating-principal-transformer", TEST_REGEX_VALIDATING_PRINCIPAL_TRANSFORMER_NAME); + private static final String TEST_REGEX_VALIDATING_PRINCIPAL_TRANSFORMER_NAME2 = "CreaperTestRegexValidatingPrincipalTransformer2"; + private static final Address TEST_REGEX_VALIDATING_PRINCIPAL_TRANSFORMER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("regex-validating-principal-transformer", TEST_REGEX_VALIDATING_PRINCIPAL_TRANSFORMER_NAME2); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_REGEX_VALIDATING_PRINCIPAL_TRANSFORMER_ADDRESS); + ops.removeIfExists(TEST_REGEX_VALIDATING_PRINCIPAL_TRANSFORMER_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleRegexValidatingPrincipalTransformer() throws Exception { + AddRegexValidatingPrincipalTransformer addRegexValidatingPrincipalTransformer + = new AddRegexValidatingPrincipalTransformer.Builder(TEST_REGEX_VALIDATING_PRINCIPAL_TRANSFORMER_NAME) + .pattern("test-pattern") + .build(); + + client.apply(addRegexValidatingPrincipalTransformer); + + assertTrue("Regex validating principal transformer should be created", + ops.exists(TEST_REGEX_VALIDATING_PRINCIPAL_TRANSFORMER_ADDRESS)); + } + + @Test + public void addTwoRegexValidatingPrincipalTransformers() throws Exception { + AddRegexValidatingPrincipalTransformer addRegexValidatingPrincipalTransformer + = new AddRegexValidatingPrincipalTransformer.Builder(TEST_REGEX_VALIDATING_PRINCIPAL_TRANSFORMER_NAME) + .pattern("test-pattern") + .build(); + AddRegexValidatingPrincipalTransformer addRegexValidatingPrincipalTransformer2 + = new AddRegexValidatingPrincipalTransformer.Builder(TEST_REGEX_VALIDATING_PRINCIPAL_TRANSFORMER_NAME2) + .pattern("test-pattern2") + .build(); + + client.apply(addRegexValidatingPrincipalTransformer); + client.apply(addRegexValidatingPrincipalTransformer2); + + assertTrue("Regex validating principal transformer should be created", + ops.exists(TEST_REGEX_VALIDATING_PRINCIPAL_TRANSFORMER_ADDRESS)); + assertTrue("Regex validating principal transformer should be created", + ops.exists(TEST_REGEX_VALIDATING_PRINCIPAL_TRANSFORMER_ADDRESS2)); + } + + @Test + public void addFullRegexValidatingPrincipalTransformer() throws Exception { + AddRegexValidatingPrincipalTransformer addRegexValidatingPrincipalTransformer + = new AddRegexValidatingPrincipalTransformer.Builder(TEST_REGEX_VALIDATING_PRINCIPAL_TRANSFORMER_NAME) + .pattern("test-pattern") + .match(true) + .build(); + + client.apply(addRegexValidatingPrincipalTransformer); + + assertTrue("Regex validating principal transformer should be created", + ops.exists(TEST_REGEX_VALIDATING_PRINCIPAL_TRANSFORMER_ADDRESS)); + checkRegexValidatingPrincipalTransformerAttribute("pattern", "test-pattern"); + checkRegexValidatingPrincipalTransformerAttribute("match", "true"); + } + + @Test(expected = CommandFailedException.class) + public void addExistRegexValidatingPrincipalTransformerNotAllowed() throws Exception { + AddRegexValidatingPrincipalTransformer addRegexValidatingPrincipalTransformer + = new AddRegexValidatingPrincipalTransformer.Builder(TEST_REGEX_VALIDATING_PRINCIPAL_TRANSFORMER_NAME) + .pattern("test-pattern") + .build(); + AddRegexValidatingPrincipalTransformer addRegexValidatingPrincipalTransformer2 + = new AddRegexValidatingPrincipalTransformer.Builder(TEST_REGEX_VALIDATING_PRINCIPAL_TRANSFORMER_NAME) + .pattern("test-pattern2") + .build(); + + client.apply(addRegexValidatingPrincipalTransformer); + assertTrue("Regex validating principal transformer should be created", + ops.exists(TEST_REGEX_VALIDATING_PRINCIPAL_TRANSFORMER_ADDRESS)); + + client.apply(addRegexValidatingPrincipalTransformer2); + fail("Regex validating principal transformer CreaperTestRegexValidatingPrincipalTransformer already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistRegexValidatingPrincipalTransformerAllowed() throws Exception { + AddRegexValidatingPrincipalTransformer addRegexValidatingPrincipalTransformer + = new AddRegexValidatingPrincipalTransformer.Builder(TEST_REGEX_VALIDATING_PRINCIPAL_TRANSFORMER_NAME) + .pattern("test-pattern") + .build(); + AddRegexValidatingPrincipalTransformer addRegexValidatingPrincipalTransformer2 + = new AddRegexValidatingPrincipalTransformer.Builder(TEST_REGEX_VALIDATING_PRINCIPAL_TRANSFORMER_NAME) + .pattern("test-pattern2") + .replaceExisting() + .build(); + + client.apply(addRegexValidatingPrincipalTransformer); + assertTrue("Regex validating principal transformer should be created", + ops.exists(TEST_REGEX_VALIDATING_PRINCIPAL_TRANSFORMER_ADDRESS)); + + client.apply(addRegexValidatingPrincipalTransformer2); + assertTrue("Regex validating principal transformer should be created", + ops.exists(TEST_REGEX_VALIDATING_PRINCIPAL_TRANSFORMER_ADDRESS)); + checkRegexValidatingPrincipalTransformerAttribute("pattern", "test-pattern2"); + } + + @Test(expected = IllegalArgumentException.class) + public void addRegexValidatingPrincipalTransformer_nullName() throws Exception { + new AddRegexValidatingPrincipalTransformer.Builder(null) + .pattern("test-pattern") + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addRegexValidatingPrincipalTransformer_emptyName() throws Exception { + new AddRegexValidatingPrincipalTransformer.Builder("") + .pattern("test-pattern") + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addRegexValidatingPrincipalTransformer_nullPattern() throws Exception { + new AddRegexValidatingPrincipalTransformer.Builder(TEST_REGEX_VALIDATING_PRINCIPAL_TRANSFORMER_NAME) + .pattern(null) + .build(); + fail("Creating command with null pattern should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addRegexValidatingPrincipalTransformer_emptyPattern() throws Exception { + new AddRegexValidatingPrincipalTransformer.Builder(TEST_REGEX_VALIDATING_PRINCIPAL_TRANSFORMER_NAME) + .pattern("") + .build(); + fail("Creating command with empty pattern should throw exception"); + } + + private void checkRegexValidatingPrincipalTransformerAttribute(String attr, String expected) throws IOException { + checkAttribute(TEST_REGEX_VALIDATING_PRINCIPAL_TRANSFORMER_ADDRESS, attr, expected); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddSimplePermissionMapperOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddSimplePermissionMapperOnlineTest.java new file mode 100644 index 00000000..db99947b --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddSimplePermissionMapperOnlineTest.java @@ -0,0 +1,300 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.ModelNodeResult; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddSimplePermissionMapperOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_SIMPLE_PERMISSION_MAPPER_NAME = "CreaperTestSimplePermissionMapper"; + private static final Address TEST_SIMPLE_PERMISSION_MAPPER_ADDRESS = SUBSYSTEM_ADDRESS + .and("simple-permission-mapper", TEST_SIMPLE_PERMISSION_MAPPER_NAME); + private static final String TEST_SIMPLE_PERMISSION_MAPPER_NAME2 = "CreaperTestSimplePermissionMapper2"; + private static final Address TEST_SIMPLE_PERMISSION_MAPPER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("simple-permission-mapper", TEST_SIMPLE_PERMISSION_MAPPER_NAME2); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_SIMPLE_PERMISSION_MAPPER_ADDRESS); + ops.removeIfExists(TEST_SIMPLE_PERMISSION_MAPPER_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addSimplePermissionMapper() throws Exception { + AddSimplePermissionMapper addSimplePermissionMapper + = new AddSimplePermissionMapper.Builder(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .build(); + + client.apply(addSimplePermissionMapper); + + assertTrue("Simple permission mapper should be created", ops.exists(TEST_SIMPLE_PERMISSION_MAPPER_ADDRESS)); + } + + @Test + public void addTwoSimplePermissionMappers() throws Exception { + AddSimplePermissionMapper addSimplePermissionMapper + = new AddSimplePermissionMapper.Builder(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .build(); + + AddSimplePermissionMapper addSimplePermissionMapper2 + = new AddSimplePermissionMapper.Builder(TEST_SIMPLE_PERMISSION_MAPPER_NAME2) + .build(); + + client.apply(addSimplePermissionMapper); + client.apply(addSimplePermissionMapper2); + + assertTrue("Simple permission mapper should be created", ops.exists(TEST_SIMPLE_PERMISSION_MAPPER_ADDRESS)); + assertTrue("Second Simple permission mapper should be created", + ops.exists(TEST_SIMPLE_PERMISSION_MAPPER_ADDRESS2)); + } + + @Test + public void addFullSimplePermissionMapper() throws Exception { + AddSimplePermissionMapper addSimplePermissionMapper + = new AddSimplePermissionMapper.Builder(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .mappingMode(AddSimplePermissionMapper.MappingMode.XOR) + .addPermissionMappings(new AddSimplePermissionMapper.PermissionMappingBuilder() + .addPermissions(new AddSimplePermissionMapper.PermissionBuilder() + .className("org.wildfly.security.auth.permission.LoginPermission") + .action("login") + .targetName("loginPermissionName") + .build(), + new AddSimplePermissionMapper.PermissionBuilder() + .className("org.wildfly.security.auth.permission.RunAsPrincipalPermission") + .action("read") + .targetName("runAsPrincipalPermissionName") + .build()) + .addRoles("SomeRoles1") + .addPrincipals("SomePrincipal1") + .build(), + new AddSimplePermissionMapper.PermissionMappingBuilder() + .addPermissions(new AddSimplePermissionMapper.PermissionBuilder() + .className("org.wildfly.security.auth.permission.ChangeRoleMapperPermission") + .action("write") + .targetName("changeRoleMapperPermissionName") + .build()) + .addRoles("SomeRoles2", "SomeRoles3") + .addPrincipals("SomePrincipal2", "SomePrincipal3") + .build()) + .build(); + + client.apply(addSimplePermissionMapper); + + assertTrue("Simple permission mapper should be created", ops.exists(TEST_SIMPLE_PERMISSION_MAPPER_ADDRESS)); + + checkSimplePermissionMapperAttribute("mapping-mode", "xor"); + + checkSimplePermissionMapperAttribute("permission-mappings[0].roles[0]", "SomeRoles1"); + checkSimplePermissionMapperAttribute("permission-mappings[0].principals[0]", "SomePrincipal1"); + checkSimplePermissionMapperAttribute("permission-mappings[0].permissions[0].class-name", + "org.wildfly.security.auth.permission.LoginPermission"); + checkSimplePermissionMapperAttribute("permission-mappings[0].permissions[0].action", "login"); + checkSimplePermissionMapperAttribute("permission-mappings[0].permissions[0].target-name", "loginPermissionName"); + + checkSimplePermissionMapperAttribute("permission-mappings[0].permissions[1].class-name", + "org.wildfly.security.auth.permission.RunAsPrincipalPermission"); + checkSimplePermissionMapperAttribute("permission-mappings[0].permissions[1].action", "read"); + checkSimplePermissionMapperAttribute("permission-mappings[0].permissions[1].target-name", + "runAsPrincipalPermissionName"); + + checkSimplePermissionMapperAttribute("permission-mappings[1].roles[0]", "SomeRoles2"); + checkSimplePermissionMapperAttribute("permission-mappings[1].roles[1]", "SomeRoles3"); + checkSimplePermissionMapperAttribute("permission-mappings[1].principals[0]", "SomePrincipal2"); + checkSimplePermissionMapperAttribute("permission-mappings[1].principals[1]", "SomePrincipal3"); + checkSimplePermissionMapperAttribute("permission-mappings[1].permissions[0].class-name", + "org.wildfly.security.auth.permission.ChangeRoleMapperPermission"); + checkSimplePermissionMapperAttribute("permission-mappings[1].permissions[0].action", "write"); + checkSimplePermissionMapperAttribute("permission-mappings[1].permissions[0].target-name", + "changeRoleMapperPermissionName"); + } + + @Test + public void addFullSimplePermissionMapper_matchAll() throws Exception { + AddSimplePermissionMapper addSimplePermissionMapper + = new AddSimplePermissionMapper.Builder(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .mappingMode(AddSimplePermissionMapper.MappingMode.OR) + .addPermissionMappings(new AddSimplePermissionMapper.PermissionMappingBuilder() + .addPermissions(new AddSimplePermissionMapper.PermissionBuilder() + .className("org.wildfly.security.auth.permission.LoginPermission") + .build()) + .matchAll(true) + .build(), + new AddSimplePermissionMapper.PermissionMappingBuilder() + .addPermissions(new AddSimplePermissionMapper.PermissionBuilder() + .className("org.wildfly.security.auth.permission.ChangeRoleMapperPermission") + .action("write") + .targetName("changeRoleMapperPermissionName") + .build()) + .matchAll(false) + .build()) + .build(); + + client.apply(addSimplePermissionMapper); + + assertTrue("Simple permission mapper should be created", ops.exists(TEST_SIMPLE_PERMISSION_MAPPER_ADDRESS)); + + checkSimplePermissionMapperAttribute("mapping-mode", "or"); + + checkSimplePermissionMapperAttribute("permission-mappings[0].match-all", "true"); + checkSimplePermissionMapperAttribute("permission-mappings[0].permissions[0].class-name", + "org.wildfly.security.auth.permission.LoginPermission"); + + checkSimplePermissionMapperAttributeIsUndefined("permission-mappings[1].match-all"); + checkSimplePermissionMapperAttribute("permission-mappings[1].permissions[0].class-name", + "org.wildfly.security.auth.permission.ChangeRoleMapperPermission"); + checkSimplePermissionMapperAttribute("permission-mappings[1].permissions[0].action", "write"); + checkSimplePermissionMapperAttribute("permission-mappings[1].permissions[0].target-name", + "changeRoleMapperPermissionName"); + } + + @Test(expected = CommandFailedException.class) + public void addExistSimplePermissionMapperNotAllowed() throws Exception { + AddSimplePermissionMapper addSimplePermissionMapper + = new AddSimplePermissionMapper.Builder(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .addPermissionMappings(new AddSimplePermissionMapper.PermissionMappingBuilder() + .addPermissions(new AddSimplePermissionMapper.PermissionBuilder() + .className("org.wildfly.security.auth.permission.LoginPermission") + .build()) + .build()) + .build(); + + AddSimplePermissionMapper addSimplePermissionMapper2 + = new AddSimplePermissionMapper.Builder(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .addPermissionMappings(new AddSimplePermissionMapper.PermissionMappingBuilder() + .addPermissions(new AddSimplePermissionMapper.PermissionBuilder() + .className("org.wildfly.security.auth.permission.ChangeRoleMapperPermission") + .targetName("someName") + .build()) + .build()) + .build(); + + client.apply(addSimplePermissionMapper); + assertTrue("Simple permission mapper should be created", ops.exists(TEST_SIMPLE_PERMISSION_MAPPER_ADDRESS)); + client.apply(addSimplePermissionMapper2); + fail("Simple permission mapper CreaperTestSimplePermissionMapper already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistSimplePermissionMapperAllowed() throws Exception { + AddSimplePermissionMapper addSimplePermissionMapper + = new AddSimplePermissionMapper.Builder(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .addPermissionMappings(new AddSimplePermissionMapper.PermissionMappingBuilder() + .addPermissions(new AddSimplePermissionMapper.PermissionBuilder() + .className("org.wildfly.security.auth.permission.LoginPermission") + .build()) + .build()) + .build(); + + AddSimplePermissionMapper addSimplePermissionMapper2 + = new AddSimplePermissionMapper.Builder(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .addPermissionMappings(new AddSimplePermissionMapper.PermissionMappingBuilder() + .addPermissions(new AddSimplePermissionMapper.PermissionBuilder() + .className("org.wildfly.security.auth.permission.ChangeRoleMapperPermission") + .targetName("someName") + .build()) + .build()) + .replaceExisting() + .build(); + + client.apply(addSimplePermissionMapper); + assertTrue("Simple permission mapper should be created", ops.exists(TEST_SIMPLE_PERMISSION_MAPPER_ADDRESS)); + client.apply(addSimplePermissionMapper2); + assertTrue("Simple permission mapper should be created", ops.exists(TEST_SIMPLE_PERMISSION_MAPPER_ADDRESS)); + // check whether it was really rewritten + checkSimplePermissionMapperAttribute("permission-mappings[0].permissions[0].class-name", + "org.wildfly.security.auth.permission.ChangeRoleMapperPermission"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSimplePermissionMapper_nullName() throws Exception { + new AddSimplePermissionMapper.Builder(null) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSimplePermissionMapper_emptyName() throws Exception { + new AddSimplePermissionMapper.Builder("") + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSimplePermissionMapper_nullClassName() throws Exception { + new AddSimplePermissionMapper.Builder(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .addPermissionMappings(new AddSimplePermissionMapper.PermissionMappingBuilder() + .addPermissions(new AddSimplePermissionMapper.PermissionBuilder() + .className(null) + .build()) + .build()) + .build(); + fail("Creating command with null class-name for permission should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSimplePermissionMapper_emptyClassName() throws Exception { + new AddSimplePermissionMapper.Builder(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .addPermissionMappings(new AddSimplePermissionMapper.PermissionMappingBuilder() + .addPermissions(new AddSimplePermissionMapper.PermissionBuilder() + .className("") + .build()) + .build()) + .build(); + fail("Creating command with empty class-name for permission should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSimplePermissionMapper_principalsMatchAll() throws Exception { + new AddSimplePermissionMapper.Builder(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .addPermissionMappings(new AddSimplePermissionMapper.PermissionMappingBuilder() + .addPermissions(new AddSimplePermissionMapper.PermissionBuilder() + .className("org.wildfly.security.auth.permission.LoginPermission") + .build()) + .addPrincipals("SomePrincipal1") + .matchAll(true) + .build()) + .build(); + fail("Creating command with both principals and match-all should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSimplePermissionMapper_rolesMatchAll() throws Exception { + new AddSimplePermissionMapper.Builder(TEST_SIMPLE_PERMISSION_MAPPER_NAME) + .addPermissionMappings(new AddSimplePermissionMapper.PermissionMappingBuilder() + .addPermissions(new AddSimplePermissionMapper.PermissionBuilder() + .className("org.wildfly.security.auth.permission.LoginPermission") + .build()) + .addRoles("SomeRole1") + .matchAll(true) + .build()) + .build(); + fail("Creating command with both roles and match-all should throw exception"); + } + + private void checkSimplePermissionMapperAttribute(String attribute, String expectedValue) throws IOException { + ModelNodeResult readAttribute = ops.readAttribute(TEST_SIMPLE_PERMISSION_MAPPER_ADDRESS, attribute); + readAttribute.assertSuccess("Read operation for " + attribute + " failed"); + assertEquals("Read operation for " + attribute + " return wrong value", expectedValue, + readAttribute.stringValue()); + } + + private void checkSimplePermissionMapperAttributeIsUndefined(String attribute) throws IOException { + ModelNodeResult readAttribute = ops.readAttribute(TEST_SIMPLE_PERMISSION_MAPPER_ADDRESS, attribute); + readAttribute.assertSuccess("Read operation for " + attribute + " failed"); + readAttribute.assertNotDefinedValue("match-all should not have defined value"); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddSimpleRegexRealmMapperOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddSimpleRegexRealmMapperOnlineTest.java new file mode 100644 index 00000000..7020f428 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddSimpleRegexRealmMapperOnlineTest.java @@ -0,0 +1,156 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddSimpleRegexRealmMapperOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_SIMPLE_REGEX_REALM_MAPPER_NAME = "CreaperTestSimpleRegexRealmMapper"; + private static final Address TEST_SIMPLE_REGEX_REALM_MAPPER_ADDRESS = SUBSYSTEM_ADDRESS + .and("simple-regex-realm-mapper", TEST_SIMPLE_REGEX_REALM_MAPPER_NAME); + private static final String TEST_SIMPLE_REGEX_REALM_MAPPER_NAME2 = "CreaperTestSimpleRegexRealmMapper2"; + private static final Address TEST_SIMPLE_REGEX_REALM_MAPPER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("simple-regex-realm-mapper", TEST_SIMPLE_REGEX_REALM_MAPPER_NAME2); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_SIMPLE_REGEX_REALM_MAPPER_ADDRESS); + ops.removeIfExists(TEST_SIMPLE_REGEX_REALM_MAPPER_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleRegexRealmMapper() throws Exception { + AddSimpleRegexRealmMapper addSimpleRegexRealmMapper + = new AddSimpleRegexRealmMapper.Builder(TEST_SIMPLE_REGEX_REALM_MAPPER_NAME) + .pattern("(somePattern)") + .build(); + + client.apply(addSimpleRegexRealmMapper); + + assertTrue("Simple regex realm mapper should be created", ops.exists(TEST_SIMPLE_REGEX_REALM_MAPPER_ADDRESS)); + } + + @Test + public void addTwoSimpleRegexRealmMappers() throws Exception { + AddSimpleRegexRealmMapper addSimpleRegexRealmMapper + = new AddSimpleRegexRealmMapper.Builder(TEST_SIMPLE_REGEX_REALM_MAPPER_NAME) + .pattern("(somePattern)") + .build(); + + AddSimpleRegexRealmMapper addSimpleRegexRealmMapper2 + = new AddSimpleRegexRealmMapper.Builder(TEST_SIMPLE_REGEX_REALM_MAPPER_NAME2) + .pattern("(somePattern)") + .build(); + + client.apply(addSimpleRegexRealmMapper); + client.apply(addSimpleRegexRealmMapper2); + + assertTrue("Simple regex realm mapper should be created", ops.exists(TEST_SIMPLE_REGEX_REALM_MAPPER_ADDRESS)); + assertTrue("Second simple regex realm mapper should be created", + ops.exists(TEST_SIMPLE_REGEX_REALM_MAPPER_ADDRESS2)); + } + + @Test + public void addFullSimpleRegexRealmMapper() throws Exception { + AddSimpleRegexRealmMapper addSimpleRegexRealmMapper2 + = new AddSimpleRegexRealmMapper.Builder(TEST_SIMPLE_REGEX_REALM_MAPPER_NAME2) + .pattern("(somePattern2)") + .build(); + client.apply(addSimpleRegexRealmMapper2); + + AddSimpleRegexRealmMapper addSimpleRegexRealmMapper + = new AddSimpleRegexRealmMapper.Builder(TEST_SIMPLE_REGEX_REALM_MAPPER_NAME) + .pattern("(somePattern)") + .delegateRealmMapper(TEST_SIMPLE_REGEX_REALM_MAPPER_NAME2) + .build(); + + client.apply(addSimpleRegexRealmMapper); + + assertTrue("Simple regex realm mapper should be created", ops.exists(TEST_SIMPLE_REGEX_REALM_MAPPER_ADDRESS)); + + checkAttribute(TEST_SIMPLE_REGEX_REALM_MAPPER_ADDRESS, "pattern", "(somePattern)"); + checkAttribute(TEST_SIMPLE_REGEX_REALM_MAPPER_ADDRESS, "delegate-realm-mapper", + TEST_SIMPLE_REGEX_REALM_MAPPER_NAME2); + } + + @Test(expected = CommandFailedException.class) + public void addExistSimpleRegexRealmMapperNotAllowed() throws Exception { + AddSimpleRegexRealmMapper addSimpleRegexRealmMapper + = new AddSimpleRegexRealmMapper.Builder(TEST_SIMPLE_REGEX_REALM_MAPPER_NAME) + .pattern("(somePattern)") + .build(); + + AddSimpleRegexRealmMapper addSimpleRegexRealmMapper2 + = new AddSimpleRegexRealmMapper.Builder(TEST_SIMPLE_REGEX_REALM_MAPPER_NAME) + .pattern("(somePattern2)") + .build(); + + client.apply(addSimpleRegexRealmMapper); + assertTrue("Simple regex realm mapper should be created", ops.exists(TEST_SIMPLE_REGEX_REALM_MAPPER_ADDRESS)); + client.apply(addSimpleRegexRealmMapper2); + fail("Simple regex realm mapper CreaperTestSimpleRegexRealmMapper already exists in configuration, exception should be thrown"); + } + + public void addExistSimpleRegexRealmMapperAllowed() throws Exception { + AddSimpleRegexRealmMapper addSimpleRegexRealmMapper + = new AddSimpleRegexRealmMapper.Builder(TEST_SIMPLE_REGEX_REALM_MAPPER_NAME) + .pattern("(somePattern)") + .build(); + + AddSimpleRegexRealmMapper addSimpleRegexRealmMapper2 + = new AddSimpleRegexRealmMapper.Builder(TEST_SIMPLE_REGEX_REALM_MAPPER_NAME) + .pattern("(somePattern2)") + .replaceExisting() + .build(); + + client.apply(addSimpleRegexRealmMapper); + assertTrue("Simple regex realm mapper should be created", ops.exists(TEST_SIMPLE_REGEX_REALM_MAPPER_ADDRESS)); + client.apply(addSimpleRegexRealmMapper2); + assertTrue("Simple regex realm mapper should be created", ops.exists(TEST_SIMPLE_REGEX_REALM_MAPPER_ADDRESS)); + // check whether it was really rewritten + checkAttribute(TEST_SIMPLE_REGEX_REALM_MAPPER_ADDRESS, "pattern", "(somePattern2)"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSimpleRegexRealmMapper_nullName() throws Exception { + new AddSimpleRegexRealmMapper.Builder(null) + .pattern("(somePattern)") + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSimpleRegexRealmMapper_emptyName() throws Exception { + new AddSimpleRegexRealmMapper.Builder("") + .pattern("(somePattern)") + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSimpleRegexRealmMapper_nullPattern() throws Exception { + new AddSimpleRegexRealmMapper.Builder(TEST_SIMPLE_REGEX_REALM_MAPPER_NAME) + .pattern(null) + .build(); + fail("Creating command with null pattern should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSimpleRegexRealmMapper_emptyPattern() throws Exception { + new AddSimpleRegexRealmMapper.Builder(TEST_SIMPLE_REGEX_REALM_MAPPER_NAME) + .pattern("") + .build(); + fail("Creating command with empty pattern should throw exception"); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddSimpleRoleDecoderOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddSimpleRoleDecoderOnlineTest.java new file mode 100644 index 00000000..eac5b0d6 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddSimpleRoleDecoderOnlineTest.java @@ -0,0 +1,129 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import java.io.IOException; +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +@RunWith(Arquillian.class) +public class AddSimpleRoleDecoderOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_SIMPLE_ROLE_DECODER_NAME = "CreaperTestSimpleRoleDecoder"; + private static final Address TEST_SIMPLE_ROLE_DECODER_ADDRESS = SUBSYSTEM_ADDRESS + .and("simple-role-decoder", TEST_SIMPLE_ROLE_DECODER_NAME); + private static final String TEST_SIMPLE_ROLE_DECODER_NAME2 = "CreaperTestSimpleRoleDecoder2"; + private static final Address TEST_SIMPLE_ROLE_DECODER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("simple-role-decoder", TEST_SIMPLE_ROLE_DECODER_NAME2); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_SIMPLE_ROLE_DECODER_ADDRESS); + ops.removeIfExists(TEST_SIMPLE_ROLE_DECODER_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleRoleDecoder() throws Exception { + AddSimpleRoleDecoder addSimpleRoleDecoder = new AddSimpleRoleDecoder.Builder(TEST_SIMPLE_ROLE_DECODER_NAME) + .attribute("groups") + .build(); + + client.apply(addSimpleRoleDecoder); + + assertTrue("Simple role decoder should be created", ops.exists(TEST_SIMPLE_ROLE_DECODER_ADDRESS)); + } + + @Test + public void addTwoSimpleRoleDecoders() throws Exception { + AddSimpleRoleDecoder addSimpleRoleDecoder = new AddSimpleRoleDecoder.Builder(TEST_SIMPLE_ROLE_DECODER_NAME) + .attribute("groups") + .build(); + AddSimpleRoleDecoder addSimpleRoleDecoder2 = new AddSimpleRoleDecoder.Builder(TEST_SIMPLE_ROLE_DECODER_NAME2) + .attribute("users") + .build(); + + client.apply(addSimpleRoleDecoder); + client.apply(addSimpleRoleDecoder2); + + assertTrue("Simple role decoder should be created", ops.exists(TEST_SIMPLE_ROLE_DECODER_ADDRESS)); + assertTrue("Simple role decoder should be created", ops.exists(TEST_SIMPLE_ROLE_DECODER_ADDRESS2)); + } + + @Test(expected = CommandFailedException.class) + public void addExistSimpleRoleDecoderNotAllowed() throws Exception { + AddSimpleRoleDecoder addSimpleRoleDecoder = new AddSimpleRoleDecoder.Builder(TEST_SIMPLE_ROLE_DECODER_NAME) + .attribute("groups") + .build(); + AddSimpleRoleDecoder addSimpleRoleDecoder2 = new AddSimpleRoleDecoder.Builder(TEST_SIMPLE_ROLE_DECODER_NAME) + .attribute("groups") + .build(); + + client.apply(addSimpleRoleDecoder); + assertTrue("Simple role decoder should be created", ops.exists(TEST_SIMPLE_ROLE_DECODER_ADDRESS)); + + client.apply(addSimpleRoleDecoder2); + fail("Simple role decoder CreaperTestSimpleRoleDecoder already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistSimpleRoleDecoderAllowed() throws Exception { + AddSimpleRoleDecoder addSimpleRoleDecoder = new AddSimpleRoleDecoder.Builder(TEST_SIMPLE_ROLE_DECODER_NAME) + .attribute("groups") + .build(); + AddSimpleRoleDecoder addSimpleRoleDecoder2 = new AddSimpleRoleDecoder.Builder(TEST_SIMPLE_ROLE_DECODER_NAME) + .attribute("users") + .replaceExisting() + .build(); + + client.apply(addSimpleRoleDecoder); + assertTrue("Simple role decoder should be created", ops.exists(TEST_SIMPLE_ROLE_DECODER_ADDRESS)); + + client.apply(addSimpleRoleDecoder2); + assertTrue("Simple role decoder should be created", ops.exists(TEST_SIMPLE_ROLE_DECODER_ADDRESS)); + + checkSimpleRoleDecoderAttribute("users"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSimpleRoleDecoder_nullName() throws Exception { + new AddSimpleRoleDecoder.Builder(null) + .attribute("groups") + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSimpleRoleDecoder_emptyName() throws Exception { + new AddSimpleRoleDecoder.Builder("") + .attribute("groups") + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSimpleRoleDecoder_nullAttribute() throws Exception { + new AddSimpleRoleDecoder.Builder(TEST_SIMPLE_ROLE_DECODER_NAME) + .attribute(null) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSimpleRoleDecoder_emptyAttribute() throws Exception { + new AddSimpleRoleDecoder.Builder(TEST_SIMPLE_ROLE_DECODER_NAME) + .attribute("") + .build(); + fail("Creating command with empty name should throw exception"); + } + + private void checkSimpleRoleDecoderAttribute(String expectedValue) throws IOException { + checkAttribute(TEST_SIMPLE_ROLE_DECODER_ADDRESS, "attribute", expectedValue); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddX500AttributePrincipalDecoderOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddX500AttributePrincipalDecoderOnlineTest.java new file mode 100644 index 00000000..7fd715ac --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/mapper/AddX500AttributePrincipalDecoderOnlineTest.java @@ -0,0 +1,211 @@ +package org.wildfly.extras.creaper.commands.elytron.mapper; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddX500AttributePrincipalDecoderOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_X500_ATTRIBUTE_PRINCIPAL_DECODER_NAME = "CreaperTestX500AttributePrincipalDecoder"; + private static final Address TEST_X500_ATTRIBUTE_PRINCIPAL_DECODER_ADDRESS = SUBSYSTEM_ADDRESS + .and("x500-attribute-principal-decoder", TEST_X500_ATTRIBUTE_PRINCIPAL_DECODER_NAME); + private static final String TEST_X500_ATTRIBUTE_PRINCIPAL_DECODER_NAME2 = "CreaperTestX500AttributePrincipalDecoder2"; + private static final Address TEST_X500_ATTRIBUTE_PRINCIPAL_DECODER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("x500-attribute-principal-decoder", TEST_X500_ATTRIBUTE_PRINCIPAL_DECODER_NAME2); + + private static final String OID1 = "test-oid1"; + private static final String OID2 = "test-oid2"; + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_X500_ATTRIBUTE_PRINCIPAL_DECODER_ADDRESS); + ops.removeIfExists(TEST_X500_ATTRIBUTE_PRINCIPAL_DECODER_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleX500AttributePrincipalDecoder() throws Exception { + AddX500AttributePrincipalDecoder addX500AttributePricipalDecoder + = new AddX500AttributePrincipalDecoder.Builder(TEST_X500_ATTRIBUTE_PRINCIPAL_DECODER_NAME) + .oid(OID1) + .build(); + + client.apply(addX500AttributePricipalDecoder); + + assertTrue("x500-attribute-principal-decoder should be created", + ops.exists(TEST_X500_ATTRIBUTE_PRINCIPAL_DECODER_ADDRESS)); + } + + @Test + public void addTwoX500AttributePrincipalDecoders() throws Exception { + AddX500AttributePrincipalDecoder addX500AttributePricipalDecoder + = new AddX500AttributePrincipalDecoder.Builder(TEST_X500_ATTRIBUTE_PRINCIPAL_DECODER_NAME) + .oid(OID1) + .build(); + + AddX500AttributePrincipalDecoder addX500AttributePricipalDecoder2 + = new AddX500AttributePrincipalDecoder.Builder(TEST_X500_ATTRIBUTE_PRINCIPAL_DECODER_NAME2) + .oid(OID2) + .build(); + + client.apply(addX500AttributePricipalDecoder); + client.apply(addX500AttributePricipalDecoder2); + + assertTrue("x500-attribute-principal-decoder should be created", + ops.exists(TEST_X500_ATTRIBUTE_PRINCIPAL_DECODER_ADDRESS)); + assertTrue("x500-attribute-principal-decoder should be created", + ops.exists(TEST_X500_ATTRIBUTE_PRINCIPAL_DECODER_ADDRESS2)); + } + + @Test + public void addFullX500AttributePrincipalDecoder_oid() throws Exception { + AddX500AttributePrincipalDecoder addX500AttributePricipalDecoder + = new AddX500AttributePrincipalDecoder.Builder(TEST_X500_ATTRIBUTE_PRINCIPAL_DECODER_NAME) + .oid(OID1) + .joiner(":") + .startSegment(2) + .maximumSegments(20) + .reverse(false) + .convert(true) + .addRequiredOids(OID1, OID2) + .build(); + + client.apply(addX500AttributePricipalDecoder); + + assertTrue("x500-attribute-principal-decoder should be created", + ops.exists(TEST_X500_ATTRIBUTE_PRINCIPAL_DECODER_ADDRESS)); + checkX500AttributePrincipalDecoderAttribute("oid", OID1); + checkX500AttributePrincipalDecoderAttribute("joiner", ":"); + checkX500AttributePrincipalDecoderAttribute("start-segment", "2"); + checkX500AttributePrincipalDecoderAttribute("maximum-segments", "20"); + checkX500AttributePrincipalDecoderAttribute("reverse", "false"); + checkX500AttributePrincipalDecoderAttribute("convert", "true"); + checkX500AttributePrincipalDecoderAttribute("maximum-segments", "20"); + checkX500AttributePrincipalDecoderAttribute("required-oids", Arrays.asList(new String[]{OID1, OID2})); + } + + @Test + public void addFullX500AttributePrincipalDecoder_attributeName() throws Exception { + AddX500AttributePrincipalDecoder addX500AttributePricipalDecoder + = new AddX500AttributePrincipalDecoder.Builder(TEST_X500_ATTRIBUTE_PRINCIPAL_DECODER_NAME) + .attributeName("cn") + .joiner(":") + .startSegment(2) + .maximumSegments(20) + .reverse(false) + .convert(true) + .build(); + + client.apply(addX500AttributePricipalDecoder); + + assertTrue("x500-attribute-principal-decoder should be created", + ops.exists(TEST_X500_ATTRIBUTE_PRINCIPAL_DECODER_ADDRESS)); + checkX500AttributePrincipalDecoderAttribute("attribute-name", "cn"); + checkX500AttributePrincipalDecoderAttribute("joiner", ":"); + checkX500AttributePrincipalDecoderAttribute("start-segment", "2"); + checkX500AttributePrincipalDecoderAttribute("maximum-segments", "20"); + checkX500AttributePrincipalDecoderAttribute("reverse", "false"); + checkX500AttributePrincipalDecoderAttribute("convert", "true"); + checkX500AttributePrincipalDecoderAttribute("maximum-segments", "20"); + } + + @Test(expected = CommandFailedException.class) + public void addExistX500AttributePrincipalDecodersNotAllowed() throws Exception { + AddX500AttributePrincipalDecoder addX500AttributePricipalDecoder + = new AddX500AttributePrincipalDecoder.Builder(TEST_X500_ATTRIBUTE_PRINCIPAL_DECODER_NAME) + .oid(OID1) + .build(); + + AddX500AttributePrincipalDecoder addX500AttributePricipalDecoder2 + = new AddX500AttributePrincipalDecoder.Builder(TEST_X500_ATTRIBUTE_PRINCIPAL_DECODER_NAME) + .oid(OID2) + .build(); + + client.apply(addX500AttributePricipalDecoder); + assertTrue("x500-attribute-principal-decoder should be created", + ops.exists(TEST_X500_ATTRIBUTE_PRINCIPAL_DECODER_ADDRESS)); + + client.apply(addX500AttributePricipalDecoder2); + fail("x500-attribute-principal-decoder CreaperTestX500AttributePrincipalDecoder already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistX500AttributePrincipalDecodersAllowed() throws Exception { + AddX500AttributePrincipalDecoder addX500AttributePricipalDecoder + = new AddX500AttributePrincipalDecoder.Builder(TEST_X500_ATTRIBUTE_PRINCIPAL_DECODER_NAME) + .oid(OID1) + .addRequiredOids(OID1) + .build(); + + AddX500AttributePrincipalDecoder addX500AttributePricipalDecoder2 + = new AddX500AttributePrincipalDecoder.Builder(TEST_X500_ATTRIBUTE_PRINCIPAL_DECODER_NAME) + .oid(OID2) + .addRequiredOids(OID2) + .replaceExisting() + .build(); + + client.apply(addX500AttributePricipalDecoder); + assertTrue("x500-attribute-principal-decoder should be created", + ops.exists(TEST_X500_ATTRIBUTE_PRINCIPAL_DECODER_ADDRESS)); + checkX500AttributePrincipalDecoderAttribute("oid", OID1); + checkX500AttributePrincipalDecoderAttribute("required-oids", Arrays.asList(OID1)); + + client.apply(addX500AttributePricipalDecoder2); + assertTrue("x500-attribute-principal-decoder should be created", + ops.exists(TEST_X500_ATTRIBUTE_PRINCIPAL_DECODER_ADDRESS)); + checkX500AttributePrincipalDecoderAttribute("oid", OID2); + checkX500AttributePrincipalDecoderAttribute("required-oids", Arrays.asList(OID2)); + } + + @Test(expected = IllegalArgumentException.class) + public void addX500AttributePrincipalDecoder_nullName() throws Exception { + new AddX500AttributePrincipalDecoder.Builder(null) + .oid(OID1) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addX500AttributePrincipalDecoder_emptyName() throws Exception { + new AddX500AttributePrincipalDecoder.Builder("") + .oid(OID1) + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addX500AttributePrincipalDecoder_NoOidAttributeName() throws Exception { + new AddX500AttributePrincipalDecoder.Builder(TEST_X500_ATTRIBUTE_PRINCIPAL_DECODER_NAME) + .build(); + fail("Creating command with none oid or attribute-name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addX500AttributePrincipalDecoder_bothOidAttributeName() throws Exception { + new AddX500AttributePrincipalDecoder.Builder(TEST_X500_ATTRIBUTE_PRINCIPAL_DECODER_NAME) + .oid("2.5.4.3") + .attributeName("dc") + .build(); + fail("Creating command with empty oid should throw exception"); + } + + private void checkX500AttributePrincipalDecoderAttribute(String attr, String expected) throws IOException { + checkAttribute(TEST_X500_ATTRIBUTE_PRINCIPAL_DECODER_ADDRESS, attr, expected); + } + + private void checkX500AttributePrincipalDecoderAttribute(String attr, List expected) throws IOException { + checkAttribute(TEST_X500_ATTRIBUTE_PRINCIPAL_DECODER_ADDRESS, attr, expected); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/providerloader/AddAggregateProvidersOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/providerloader/AddAggregateProvidersOnlineTest.java new file mode 100644 index 00000000..09865bb9 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/providerloader/AddAggregateProvidersOnlineTest.java @@ -0,0 +1,177 @@ +package org.wildfly.extras.creaper.commands.elytron.providerloader; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddAggregateProvidersOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_AGGREGATE_PROVIDERS_NAME = "CreaperTestAggregateProviders"; + private static final Address TEST_AGGREGATE_PROVIDERS_ADDRESS = SUBSYSTEM_ADDRESS + .and("aggregate-providers", TEST_AGGREGATE_PROVIDERS_NAME); + private static final String TEST_AGGREGATE_PROVIDERS_NAME2 = "CreaperTestAggregateProviders2"; + private static final Address TEST_AGGREGATE_PROVIDERS_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("aggregate-providers", TEST_AGGREGATE_PROVIDERS_NAME2); + + protected static final String TEST_PROVIDER_LOADER_NAME = "CreaperTestProviderLoader"; + protected static final Address TEST_PROVIDER_LOADER_ADDRESS = SUBSYSTEM_ADDRESS + .and("provider-loader", TEST_PROVIDER_LOADER_NAME); + protected static final String TEST_PROVIDER_LOADER_NAME2 = "CreaperTestProviderLoader2"; + protected static final Address TEST_PROVIDER_LOADER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("provider-loader", TEST_PROVIDER_LOADER_NAME2); + + @Before + public void createProviderLoaders() throws Exception { + AddProviderLoader addProviderLoader = new AddProviderLoader.Builder(TEST_PROVIDER_LOADER_NAME) + .build(); + AddProviderLoader addProviderLoader2 = new AddProviderLoader.Builder(TEST_PROVIDER_LOADER_NAME2) + .build(); + client.apply(addProviderLoader); + client.apply(addProviderLoader2); + } + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_AGGREGATE_PROVIDERS_ADDRESS); + ops.removeIfExists(TEST_AGGREGATE_PROVIDERS_ADDRESS2); + ops.removeIfExists(TEST_PROVIDER_LOADER_ADDRESS); + ops.removeIfExists(TEST_PROVIDER_LOADER_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addAggregateProviders() throws Exception { + AddAggregateProviders addAggregateProviders + = new AddAggregateProviders.Builder(TEST_AGGREGATE_PROVIDERS_NAME) + .providers(TEST_PROVIDER_LOADER_NAME, TEST_PROVIDER_LOADER_NAME2) + .build(); + + client.apply(addAggregateProviders); + + assertTrue("Aggregate-providers should be created", ops.exists(TEST_AGGREGATE_PROVIDERS_ADDRESS)); + checkAttribute(TEST_AGGREGATE_PROVIDERS_ADDRESS, "providers[0]", TEST_PROVIDER_LOADER_NAME); + checkAttribute(TEST_AGGREGATE_PROVIDERS_ADDRESS, "providers[1]", TEST_PROVIDER_LOADER_NAME2); + } + + @Test + public void addTwoAggregateProviders() throws Exception { + AddAggregateProviders addAggregateProviders + = new AddAggregateProviders.Builder(TEST_AGGREGATE_PROVIDERS_NAME) + .providers(TEST_PROVIDER_LOADER_NAME, TEST_PROVIDER_LOADER_NAME2) + .build(); + + AddAggregateProviders addAggregateProviders2 + = new AddAggregateProviders.Builder(TEST_AGGREGATE_PROVIDERS_NAME2) + .providers(TEST_PROVIDER_LOADER_NAME2, TEST_PROVIDER_LOADER_NAME2) + .build(); + + client.apply(addAggregateProviders); + client.apply(addAggregateProviders2); + + assertTrue("Aggregate-providers should be created", ops.exists(TEST_AGGREGATE_PROVIDERS_ADDRESS)); + assertTrue("Second aggregate-providers should be created", ops.exists(TEST_AGGREGATE_PROVIDERS_ADDRESS2)); + } + + @Test(expected = CommandFailedException.class) + public void addExistAggregateProvidersNotAllowed() throws Exception { + AddAggregateProviders addAggregateProviders + = new AddAggregateProviders.Builder(TEST_AGGREGATE_PROVIDERS_NAME) + .providers(TEST_PROVIDER_LOADER_NAME, TEST_PROVIDER_LOADER_NAME2) + .build(); + + AddAggregateProviders addAggregateProviders2 + = new AddAggregateProviders.Builder(TEST_AGGREGATE_PROVIDERS_NAME) + .providers(TEST_PROVIDER_LOADER_NAME2, TEST_PROVIDER_LOADER_NAME2) + .build(); + + client.apply(addAggregateProviders); + assertTrue("Aggregate-providers should be created", ops.exists(TEST_AGGREGATE_PROVIDERS_ADDRESS)); + + client.apply(addAggregateProviders2); + fail("Aggregate-providers CreaperTestAggregateProviders already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistAggregateProvidersAllowed() throws Exception { + AddAggregateProviders addAggregateProviders + = new AddAggregateProviders.Builder(TEST_AGGREGATE_PROVIDERS_NAME) + .providers(TEST_PROVIDER_LOADER_NAME, TEST_PROVIDER_LOADER_NAME2) + .build(); + + AddAggregateProviders addAggregateProviders2 + = new AddAggregateProviders.Builder(TEST_AGGREGATE_PROVIDERS_NAME) + .providers(TEST_PROVIDER_LOADER_NAME2, TEST_PROVIDER_LOADER_NAME2) + .replaceExisting() + .build(); + + client.apply(addAggregateProviders); + assertTrue("Aggregate-providers should be created", ops.exists(TEST_AGGREGATE_PROVIDERS_ADDRESS)); + + client.apply(addAggregateProviders2); + assertTrue("Aggregate-providers should be created", ops.exists(TEST_AGGREGATE_PROVIDERS_ADDRESS)); + + // check whether it was really rewritten + checkAttribute(TEST_AGGREGATE_PROVIDERS_ADDRESS, "providers[1]", TEST_PROVIDER_LOADER_NAME2); + } + + @Test(expected = CommandFailedException.class) + public void addAggregateProvidersWithoutConfiguredProviderLoader() throws Exception { + AddAggregateProviders addAggregateProviders + = new AddAggregateProviders.Builder(TEST_AGGREGATE_PROVIDERS_NAME) + .providers(TEST_PROVIDER_LOADER_NAME, "NotConfiguredProviderLoader") + .build(); + + client.apply(addAggregateProviders); + fail("Aggregate-providers shouldn't be added when using unconfigured provider-loader"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregateProviders_nullName() throws Exception { + new AddAggregateProviders.Builder(null) + .providers(TEST_PROVIDER_LOADER_NAME, TEST_PROVIDER_LOADER_NAME2) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregateProviders_emptyName() throws Exception { + new AddAggregateProviders.Builder("") + .providers(TEST_PROVIDER_LOADER_NAME, TEST_PROVIDER_LOADER_NAME2) + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregateProviders_nullProviders() throws Exception { + new AddAggregateProviders.Builder(TEST_AGGREGATE_PROVIDERS_NAME) + .providers(null) + .build(); + fail("Creating command with null providers should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregateProviders_emptyProviders() throws Exception { + new AddAggregateProviders.Builder(TEST_AGGREGATE_PROVIDERS_NAME) + .providers("") + .build(); + fail("Creating command with empty providers should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregateProviders_oneProvider() throws Exception { + new AddAggregateProviders.Builder(TEST_AGGREGATE_PROVIDERS_NAME) + .providers(TEST_PROVIDER_LOADER_NAME) + .build(); + fail("Creating command with only one provider should throw exception"); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/providerloader/AddProviderLoaderImpl.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/providerloader/AddProviderLoaderImpl.java new file mode 100644 index 00000000..c1d66aa4 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/providerloader/AddProviderLoaderImpl.java @@ -0,0 +1,17 @@ +package org.wildfly.extras.creaper.commands.elytron.providerloader; + +import java.security.Provider; + +public class AddProviderLoaderImpl extends Provider { + + private static final long serialVersionUID = 6200844516312931250L; + + public AddProviderLoaderImpl() { + super("name", 1.0, "some info"); + } + + public AddProviderLoaderImpl(String argument) { + this(); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/providerloader/AddProviderLoaderOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/providerloader/AddProviderLoaderOnlineTest.java new file mode 100644 index 00000000..0a627ec5 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/providerloader/AddProviderLoaderOnlineTest.java @@ -0,0 +1,254 @@ +package org.wildfly.extras.creaper.commands.elytron.providerloader; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.IOException; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.commands.modules.AddModule; +import org.wildfly.extras.creaper.commands.modules.RemoveModule; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddProviderLoaderOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_PROVIDER_LOADER_NAME = "CreaperTestProviderLoader"; + private static final Address TEST_PROVIDER_LOADER_ADDRESS = SUBSYSTEM_ADDRESS.and("provider-loader", + TEST_PROVIDER_LOADER_NAME); + private static final String TEST_PROVIDER_LOADER_NAME2 = "CreaperTestProviderLoader2"; + private static final Address TEST_PROVIDER_LOADER_ADDRESS2 = SUBSYSTEM_ADDRESS.and("provider-loader", + TEST_PROVIDER_LOADER_NAME2); + + private static final String TEST_MODULE_NAME = "com.example.creaper-test-module"; + + @Rule + public TemporaryFolder tmp = new TemporaryFolder(); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_PROVIDER_LOADER_ADDRESS); + ops.removeIfExists(TEST_PROVIDER_LOADER_ADDRESS2); + removeModuleQuietly(); + + administration.reloadIfRequired(); + } + + @Test + public void addSimpleProviderLoader() throws Exception { + AddProviderLoader addProviderLoader = new AddProviderLoader.Builder(TEST_PROVIDER_LOADER_NAME) + .build(); + + client.apply(addProviderLoader); + + assertTrue("Provider loader should be created", ops.exists(TEST_PROVIDER_LOADER_ADDRESS)); + } + + @Test + public void addTwoProviderLoaders() throws Exception { + AddProviderLoader addProviderLoader = new AddProviderLoader.Builder(TEST_PROVIDER_LOADER_NAME) + .build(); + AddProviderLoader addProviderLoader2 = new AddProviderLoader.Builder(TEST_PROVIDER_LOADER_NAME2) + .build(); + + client.apply(addProviderLoader); + client.apply(addProviderLoader2); + + assertTrue("Provider loader should be created", ops.exists(TEST_PROVIDER_LOADER_ADDRESS)); + assertTrue("Second provider loader should be created", ops.exists(TEST_PROVIDER_LOADER_ADDRESS2)); + } + + @Test + public void addFullProviderLoaderConfiguration() throws Exception { + File testJar1 = createJar("testJar", AddProviderLoaderImpl.class); + AddModule addModule = new AddModule.Builder(TEST_MODULE_NAME) + .resource(testJar1) + .build(); + client.apply(addModule); + + AddProviderLoader addProviderLoader = new AddProviderLoader.Builder(TEST_PROVIDER_LOADER_NAME) + .module(TEST_MODULE_NAME) + .classNames(AddProviderLoaderImpl.class.getCanonicalName()) + .addConfiguration("configurationName", "configurationValue") + .build(); + + client.apply(addProviderLoader); + + assertTrue("Provider loader should be created", ops.exists(TEST_PROVIDER_LOADER_ADDRESS)); + checkAttribute(TEST_PROVIDER_LOADER_ADDRESS, "module", TEST_MODULE_NAME); + checkAttribute(TEST_PROVIDER_LOADER_ADDRESS, "class-names[0]", AddProviderLoaderImpl.class.getCanonicalName()); + checkAttribute(TEST_PROVIDER_LOADER_ADDRESS, "configuration.configurationName", "configurationValue"); + } + + @Test + public void addFullProviderLoaderPath() throws Exception { + File testJar1 = createJar("testJar", AddProviderLoaderImpl.class); + + AddModule addModule = new AddModule.Builder(TEST_MODULE_NAME) + .resource(testJar1) + .build(); + client.apply(addModule); + + AddProviderLoader addProviderLoader = new AddProviderLoader.Builder(TEST_PROVIDER_LOADER_NAME) + .module(TEST_MODULE_NAME) + .classNames(AddProviderLoaderImpl.class.getCanonicalName()) + .path("application-users.properties") + .relativeTo("jboss.server.config.dir") + .build(); + + client.apply(addProviderLoader); + + assertTrue("Provider loader should be created", ops.exists(TEST_PROVIDER_LOADER_ADDRESS)); + checkAttribute(TEST_PROVIDER_LOADER_ADDRESS, "module", TEST_MODULE_NAME); + checkAttribute(TEST_PROVIDER_LOADER_ADDRESS, "class-names[0]", AddProviderLoaderImpl.class.getCanonicalName()); + checkAttribute(TEST_PROVIDER_LOADER_ADDRESS, "path", "application-users.properties"); + checkAttribute(TEST_PROVIDER_LOADER_ADDRESS, "relative-to", "jboss.server.config.dir"); + } + + @Test + public void addProviderLoaderArgument() throws Exception { + File testJar1 = createJar("testJar", AddProviderLoaderImpl.class); + + AddModule addModule = new AddModule.Builder(TEST_MODULE_NAME) + .resource(testJar1) + .build(); + client.apply(addModule); + + AddProviderLoader addProviderLoader = new AddProviderLoader.Builder(TEST_PROVIDER_LOADER_NAME) + .module(TEST_MODULE_NAME) + .classNames(AddProviderLoaderImpl.class.getCanonicalName()) + .argument("constructor_argument") + .build(); + + client.apply(addProviderLoader); + + assertTrue("Provider loader should be created", ops.exists(TEST_PROVIDER_LOADER_ADDRESS)); + checkAttribute(TEST_PROVIDER_LOADER_ADDRESS, "module", TEST_MODULE_NAME); + checkAttribute(TEST_PROVIDER_LOADER_ADDRESS, "class-names[0]", AddProviderLoaderImpl.class.getCanonicalName()); + checkAttribute(TEST_PROVIDER_LOADER_ADDRESS, "argument", "constructor_argument"); + } + + @Test + public void addProviderLoaderConfiguration() throws Exception { + File testJar1 = createJar("testJar", AddProviderLoaderImpl.class); + + AddModule addModule = new AddModule.Builder(TEST_MODULE_NAME) + .resource(testJar1) + .build(); + client.apply(addModule); + + AddProviderLoader addProviderLoader = new AddProviderLoader.Builder(TEST_PROVIDER_LOADER_NAME) + .module(TEST_MODULE_NAME) + .classNames(AddProviderLoaderImpl.class.getCanonicalName()) + .addConfiguration("key", "value") + .build(); + + client.apply(addProviderLoader); + + assertTrue("Provider loader should be created", ops.exists(TEST_PROVIDER_LOADER_ADDRESS)); + checkAttribute(TEST_PROVIDER_LOADER_ADDRESS, "module", TEST_MODULE_NAME); + checkAttribute(TEST_PROVIDER_LOADER_ADDRESS, "class-names[0]", AddProviderLoaderImpl.class.getCanonicalName()); + checkAttributeObject(TEST_PROVIDER_LOADER_ADDRESS, "configuration", "key", "value"); + } + + @Test(expected = CommandFailedException.class) + public void addExistProviderLoaderNotAllowed() throws Exception { + AddProviderLoader addProviderLoader = new AddProviderLoader.Builder(TEST_PROVIDER_LOADER_NAME) + .build(); + AddProviderLoader addProviderLoader2 = new AddProviderLoader.Builder(TEST_PROVIDER_LOADER_NAME) + .build(); + + client.apply(addProviderLoader); + assertTrue("Provider loader should be created", ops.exists(TEST_PROVIDER_LOADER_ADDRESS)); + client.apply(addProviderLoader2); + fail("Provider loader CreaperTestProviderLoader already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistProviderLoaderAllowed() throws Exception { + AddProviderLoader addProviderLoader = new AddProviderLoader.Builder(TEST_PROVIDER_LOADER_NAME) + .build(); + AddProviderLoader addProviderLoader2 = new AddProviderLoader.Builder(TEST_PROVIDER_LOADER_NAME) + .addConfiguration("configurationName", "configurationValue") + .replaceExisting() + .build(); + + client.apply(addProviderLoader); + assertTrue("Provider loader should be created", ops.exists(TEST_PROVIDER_LOADER_ADDRESS)); + client.apply(addProviderLoader2); + + // check whether it was really rewritten + checkAttribute(TEST_PROVIDER_LOADER_ADDRESS, "configuration.configurationName", "configurationValue"); + } + + @Test(expected = IllegalArgumentException.class) + public void addProviderLoader_configurationAndPath() throws Exception { + new AddProviderLoader.Builder(TEST_PROVIDER_LOADER_NAME) + .addConfiguration("configurationName", "configurationValue") + .path("application-users.properties") + .build(); + } + + @Test(expected = IllegalArgumentException.class) + public void addProviderLoader_configurationAndArgument() throws Exception { + new AddProviderLoader.Builder(TEST_PROVIDER_LOADER_NAME) + .addConfiguration("configurationName", "configurationValue") + .argument("argument") + .build(); + } + + @Test(expected = IllegalArgumentException.class) + public void addProviderLoader_pathAndArgument() throws Exception { + new AddProviderLoader.Builder(TEST_PROVIDER_LOADER_NAME) + .path("path") + .argument("argument") + .build(); + } + + @Test(expected = IllegalArgumentException.class) + public void addProviderLoader_nullName() throws Exception { + new AddProviderLoader.Builder(null) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addProviderLoader_emptyName() throws Exception { + new AddProviderLoader.Builder("") + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addProviderLoader_nullClassNames() throws Exception { + new AddProviderLoader.Builder(TEST_PROVIDER_LOADER_NAME) + .classNames(null) + .build(); + fail("Creating command with null class-names should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addProviderLoader_nullConfiguration() throws Exception { + new AddProviderLoader.Builder(TEST_PROVIDER_LOADER_NAME) + .addConfiguration(null, null) + .build(); + fail("Creating command with null configuration should throw exception"); + } + + private void removeModuleQuietly() throws IOException { + try { + RemoveModule removeModule = new RemoveModule(TEST_MODULE_NAME); + client.apply(removeModule); + } catch (CommandFailedException ignore) { + // ignored + } + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddAggregateRealmOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddAggregateRealmOnlineTest.java new file mode 100644 index 00000000..f1814d10 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddAggregateRealmOnlineTest.java @@ -0,0 +1,181 @@ +package org.wildfly.extras.creaper.commands.elytron.realm; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.OperationException; + +@RunWith(Arquillian.class) +public class AddAggregateRealmOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_AGGREGATE_REALM_NAME = "CreaperTestAggregateRealm"; + private static final Address TEST_AGGREGATE_REALM_ADDRESS = SUBSYSTEM_ADDRESS.and("aggregate-realm", + TEST_AGGREGATE_REALM_NAME); + private static final String TEST_AGGREGATE_REALM_NAME2 = "CreaperTestAggregateRealm2"; + private static final Address TEST_AGGREGATE_REALM_ADDRESS2 = SUBSYSTEM_ADDRESS.and("aggregate-realm", + TEST_AGGREGATE_REALM_NAME2); + + private static final String FILESYSTEM_REALM_TYPE = "filesystem-realm"; + private static final String TEST_DEFAULT_FILESYSTEM_REALM_NAME = "CreaperTestFilesystemRealm"; + + public AddAggregateRealmOnlineTest() { + super(); + } + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_AGGREGATE_REALM_ADDRESS); + ops.removeIfExists(TEST_AGGREGATE_REALM_ADDRESS2); + + removeAllFilesystemRealms(); + + administration.reloadIfRequired(); + } + + @Test + public void addAggregateRealm() throws Exception { + addDefaultFilesystemRealm(); + + AddAggregateRealm addAggregateRealm = new AddAggregateRealm.Builder(TEST_AGGREGATE_REALM_NAME) + .authenticationRealm(TEST_DEFAULT_FILESYSTEM_REALM_NAME) + .authorizationRealm(TEST_DEFAULT_FILESYSTEM_REALM_NAME) + .build(); + + client.apply(addAggregateRealm); + + assertTrue("Aggregate realm should be created", ops.exists(TEST_AGGREGATE_REALM_ADDRESS)); + } + + @Test(expected = CommandFailedException.class) + public void addAggregateRealm_nonAuthenticationRealm() throws Exception { + addDefaultFilesystemRealm(); + + AddAggregateRealm addAggregateRealm = new AddAggregateRealm.Builder(TEST_AGGREGATE_REALM_NAME) + .authenticationRealm("nonExistRealm").authorizationRealm(TEST_DEFAULT_FILESYSTEM_REALM_NAME).build(); + + client.apply(addAggregateRealm); + + fail("Creating command with non existing realms should throw exception"); + } + + @Test(expected = CommandFailedException.class) + public void addAggregateRealm_nonAuthorizationRealm() throws Exception { + addDefaultFilesystemRealm(); + + AddAggregateRealm addAggregateRealm = new AddAggregateRealm.Builder(TEST_AGGREGATE_REALM_NAME) + .authenticationRealm(TEST_DEFAULT_FILESYSTEM_REALM_NAME) + .authorizationRealm("nonExistRealm") + .build(); + + client.apply(addAggregateRealm); + + fail("Creating command with non existing realms should throw exception"); + } + + @Test + public void addAggregateRealms() throws Exception { + addFilesystemRealm("filesystemRealm1"); + addFilesystemRealm("filesystemRealm2"); + + AddAggregateRealm addAggregateRealm = new AddAggregateRealm.Builder(TEST_AGGREGATE_REALM_NAME) + .authenticationRealm("filesystemRealm1") + .authorizationRealm("filesystemRealm2") + .build(); + + AddAggregateRealm addAggregateRealm2 = new AddAggregateRealm.Builder(TEST_AGGREGATE_REALM_NAME2) + .authenticationRealm("filesystemRealm1") + .authorizationRealm("filesystemRealm2") + .build(); + + client.apply(addAggregateRealm); + client.apply(addAggregateRealm2); + + assertTrue("Aggregate realm should be created", ops.exists(TEST_AGGREGATE_REALM_ADDRESS)); + assertTrue("Second aggregate realm should be created", ops.exists(TEST_AGGREGATE_REALM_ADDRESS2)); + + checkAttribute(TEST_AGGREGATE_REALM_ADDRESS, "authentication-realm", "filesystemRealm1"); + checkAttribute(TEST_AGGREGATE_REALM_ADDRESS2, "authorization-realm", "filesystemRealm2"); + + administration.reload(); + + checkAttribute(TEST_AGGREGATE_REALM_ADDRESS, "authentication-realm", "filesystemRealm1"); + checkAttribute(TEST_AGGREGATE_REALM_ADDRESS2, "authorization-realm", "filesystemRealm2"); + } + + @Test(expected = CommandFailedException.class) + public void addDuplicateAggregateRealmNotAllowed() throws Exception { + addFilesystemRealm("filesystemRealm1"); + + AddAggregateRealm addAggregateRealm = new AddAggregateRealm.Builder(TEST_AGGREGATE_REALM_NAME) + .authenticationRealm("filesystemRealm1").authorizationRealm("filesystemRealm1").build(); + + client.apply(addAggregateRealm); + assertTrue("Aggregate realm should be created", ops.exists(TEST_AGGREGATE_REALM_ADDRESS)); + client.apply(addAggregateRealm); + fail("Aggregate realm " + TEST_AGGREGATE_REALM_NAME + + " already exists in configuration, exception should be thrown"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregateRealm_nullName() throws Exception { + new AddAggregateRealm.Builder(null); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregateRealm_emptyName() throws Exception { + new AddAggregateRealm.Builder(""); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregateRealm_noRealms() throws Exception { + new AddAggregateRealm.Builder(TEST_AGGREGATE_REALM_NAME).build(); + fail("Creating command with no realm should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregateRealm_noAuthenticationRealm() throws Exception { + addFilesystemRealm("filesystemRealm1"); + + new AddAggregateRealm.Builder(TEST_AGGREGATE_REALM_NAME) + .authenticationRealm(null) + .authorizationRealm(TEST_DEFAULT_FILESYSTEM_REALM_NAME) + .build(); + fail("Creating command with no realm should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregateRealm_noAuthorizationRealm() throws Exception { + addFilesystemRealm("filesystemRealm1"); + + new AddAggregateRealm.Builder(TEST_AGGREGATE_REALM_NAME) + .authenticationRealm(TEST_DEFAULT_FILESYSTEM_REALM_NAME) + .authorizationRealm(null) + .build(); + fail("Creating command with no realm should throw exception"); + } + + private void addDefaultFilesystemRealm() throws CommandFailedException { + addFilesystemRealm(TEST_DEFAULT_FILESYSTEM_REALM_NAME); + } + + private void addFilesystemRealm(String realmName) throws CommandFailedException { + AddFilesystemRealm addAddPrefixRealm = new AddFilesystemRealm.Builder(realmName) + .path("/path/to/filesystem").build(); + client.apply(addAddPrefixRealm); + } + + private void removeAllFilesystemRealms() throws IOException, OperationException { + removeAllElytronChildrenType(FILESYSTEM_REALM_TYPE); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCachingRealmOfflineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCachingRealmOfflineTest.java new file mode 100644 index 00000000..85565e78 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCachingRealmOfflineTest.java @@ -0,0 +1,215 @@ +package org.wildfly.extras.creaper.commands.elytron.realm; + +import static org.junit.Assert.fail; +import static org.wildfly.extras.creaper.XmlAssert.assertXmlIdentical; +import com.google.common.base.Charsets; +import com.google.common.io.Files; +import java.io.File; +import org.custommonkey.xmlunit.XMLUnit; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.ManagementClient; +import org.wildfly.extras.creaper.core.offline.OfflineManagementClient; +import org.wildfly.extras.creaper.core.offline.OfflineOptions; + +public class AddCachingRealmOfflineTest { + + private static final String SUBSYSTEM_EMPTY = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_REALMS_EMPTY = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_SIMPLE = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_EXPECTED_REPLACE = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_SECOND_KEY_STORE = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_FULL = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + @Rule + public final TemporaryFolder tmp = new TemporaryFolder(); + + @Before + public void setUp() { + XMLUnit.setNormalizeWhitespace(true); + } + + @Test + public void addSimpleToEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddCachingRealm addCachingRealm = new AddCachingRealm.Builder("creaperCachingRealm") + .realm("cachedRealm") + .build(); + + assertXmlIdentical(SUBSYSTEM_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addCachingRealm); + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addSimpleToCachingRealmsEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_REALMS_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddCachingRealm addCachingRealm = new AddCachingRealm.Builder("creaperCachingRealm") + .realm("cachedRealm") + .build(); + + assertXmlIdentical(SUBSYSTEM_REALMS_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addCachingRealm); + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test(expected = CommandFailedException.class) + public void existing() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddCachingRealm addCachingRealm = new AddCachingRealm.Builder("creaperCachingRealm") + .realm("cachedRealm") + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addCachingRealm); + + fail("Key store creaperCachingRealm already exists in configuration, exception should be thrown"); + } + + @Test + public void overrideExisting() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddCachingRealm addCachingRealm = new AddCachingRealm.Builder("creaperCachingRealm") + .realm("cachedRealm2") + .replaceExisting() + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addCachingRealm); + assertXmlIdentical(SUBSYSTEM_EXPECTED_REPLACE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void overrideNonExisting() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddCachingRealm addCachingRealm = new AddCachingRealm.Builder("creaperCachingRealm2") + .realm("cachedRealm") + .replaceExisting() + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addCachingRealm); + assertXmlIdentical(SUBSYSTEM_SECOND_KEY_STORE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addSecondCachingRealm() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddCachingRealm addCachingRealm = new AddCachingRealm.Builder("creaperCachingRealm2") + .realm("cachedRealm") + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addCachingRealm); + assertXmlIdentical(SUBSYSTEM_SECOND_KEY_STORE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addFullToEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddCachingRealm addCachingRealm = new AddCachingRealm.Builder("creaperCachingRealm") + .realm("cachedRealm") + .maximumEntries(200) + .maximumAge(60000) + .build(); + + assertXmlIdentical(SUBSYSTEM_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addCachingRealm); + assertXmlIdentical(SUBSYSTEM_FULL, Files.toString(cfg, Charsets.UTF_8)); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCachingRealmOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCachingRealmOnlineTest.java new file mode 100644 index 00000000..d8508e5f --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCachingRealmOnlineTest.java @@ -0,0 +1,152 @@ +package org.wildfly.extras.creaper.commands.elytron.realm; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.OperationException; + +@RunWith(Arquillian.class) +public class AddCachingRealmOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_CACHING_REALM_NAME = "CreaperTestCachingRealm"; + private static final Address TEST_CACHING_REALM_ADDRESS = SUBSYSTEM_ADDRESS.and("caching-realm", + TEST_CACHING_REALM_NAME); + private static final String TEST_CACHING_REALM_NAME2 = "CreaperTestCachingRealm2"; + private static final Address TEST_CACHING_REALM_ADDRESS2 = SUBSYSTEM_ADDRESS.and("caching-realm", + TEST_CACHING_REALM_NAME2); + + private static final String FILESYSTEM_REALM_TYPE = "filesystem-realm"; + private static final String TEST_DEFAULT_FILESYSTEM_REALM_NAME = "CreaperTestFilesystemRealm"; + + public AddCachingRealmOnlineTest() { + super(); + } + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_CACHING_REALM_ADDRESS); + ops.removeIfExists(TEST_CACHING_REALM_ADDRESS2); + + removeAllFilesystemRealms(); + + administration.reloadIfRequired(); + } + + @Test + public void addCachingRealm() throws Exception { + addDefaultFilesystemRealm(); + + AddCachingRealm addCachingRealm = new AddCachingRealm.Builder(TEST_CACHING_REALM_NAME) + .realm(TEST_DEFAULT_FILESYSTEM_REALM_NAME) + .build(); + + client.apply(addCachingRealm); + + assertTrue("Caching realm should be created", ops.exists(TEST_CACHING_REALM_ADDRESS)); + } + + @Test(expected = CommandFailedException.class) + public void addCachingRealm_nonAuthenticationRealm() throws Exception { + addDefaultFilesystemRealm(); + + AddCachingRealm addCachingRealm = new AddCachingRealm.Builder(TEST_CACHING_REALM_NAME) + .realm("nonExistRealm").build(); + + client.apply(addCachingRealm); + + fail("Creating command with non existing realms should throw exception"); + } + + @Test + public void addCachingRealms() throws Exception { + addFilesystemRealm("filesystemRealm1"); + addFilesystemRealm("filesystemRealm2"); + + AddCachingRealm addCachingRealm = new AddCachingRealm.Builder(TEST_CACHING_REALM_NAME) + .realm("filesystemRealm1") + .build(); + + AddCachingRealm addCachingRealm2 = new AddCachingRealm.Builder(TEST_CACHING_REALM_NAME2) + .realm("filesystemRealm1") + .build(); + + client.apply(addCachingRealm); + client.apply(addCachingRealm2); + + assertTrue("Caching realm should be created", ops.exists(TEST_CACHING_REALM_ADDRESS)); + assertTrue("Second caching realm should be created", ops.exists(TEST_CACHING_REALM_ADDRESS2)); + + checkAttribute(TEST_CACHING_REALM_ADDRESS, "realm", "filesystemRealm1"); + checkAttribute(TEST_CACHING_REALM_ADDRESS2, "realm", "filesystemRealm1"); + + administration.reload(); + + checkAttribute(TEST_CACHING_REALM_ADDRESS, "realm", "filesystemRealm1"); + checkAttribute(TEST_CACHING_REALM_ADDRESS2, "realm", "filesystemRealm1"); + } + + @Test(expected = CommandFailedException.class) + public void addDuplicateCachingRealmNotAllowed() throws Exception { + addFilesystemRealm("filesystemRealm1"); + + AddCachingRealm addCachingRealm = new AddCachingRealm.Builder(TEST_CACHING_REALM_NAME) + .realm("filesystemRealm1").build(); + + client.apply(addCachingRealm); + assertTrue("Caching realm should be created", ops.exists(TEST_CACHING_REALM_ADDRESS)); + client.apply(addCachingRealm); + fail("Caching realm " + TEST_CACHING_REALM_NAME + + " already exists in configuration, exception should be thrown"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCachingRealm_nullName() throws Exception { + new AddCachingRealm.Builder(null); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCachingRealm_emptyName() throws Exception { + new AddCachingRealm.Builder(""); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCachingRealm_noRealms() throws Exception { + new AddCachingRealm.Builder(TEST_CACHING_REALM_NAME).build(); + fail("Creating command with no realm should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCachingRealm_noAuthenticationRealm() throws Exception { + addFilesystemRealm("filesystemRealm1"); + + new AddCachingRealm.Builder(TEST_CACHING_REALM_NAME) + .realm(null) + .build(); + fail("Creating command with no realm should throw exception"); + } + + private void addDefaultFilesystemRealm() throws CommandFailedException { + addFilesystemRealm(TEST_DEFAULT_FILESYSTEM_REALM_NAME); + } + + private void addFilesystemRealm(String realmName) throws CommandFailedException { + AddFilesystemRealm addAddPrefixRealm = new AddFilesystemRealm.Builder(realmName) + .path("/path/to/filesystem").build(); + client.apply(addAddPrefixRealm); + } + + private void removeAllFilesystemRealms() throws IOException, OperationException { + removeAllElytronChildrenType(FILESYSTEM_REALM_TYPE); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomModifiableRealmOfflineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomModifiableRealmOfflineTest.java new file mode 100644 index 00000000..7bcacc68 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomModifiableRealmOfflineTest.java @@ -0,0 +1,34 @@ +package org.wildfly.extras.creaper.commands.elytron.realm; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractAddCustomOfflineTest; + + +@RunWith(Arquillian.class) +public class AddCustomModifiableRealmOfflineTest extends AbstractAddCustomOfflineTest { + + public String convertSubsystem(String subsystemString) { + return subsystemString.replaceAll(PARENT_TYPE, "security-realms") + .replaceAll(CUSTOM_TYPE, "custom-realm") + .replaceAll(CUSTOM_NAME, getAddCustomName()) + .replaceAll(CLASS_NAME, getClassName()) + .replaceAll(MODULE_NAME, getModuleName()); + } + + public String getAddCustomName() { + return "customRealm"; + } + + public Object getBuilderObject(String name) { + return new AddCustomRealm.Builder(name); + } + + public String getModuleName() { + return "org.jboss.customrealmimpl"; + } + + public String getClassName() { + return "SomeCustomRealm"; + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomModifiableRealmOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomModifiableRealmOnlineTest.java new file mode 100644 index 00000000..687e8a9c --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomModifiableRealmOnlineTest.java @@ -0,0 +1,65 @@ +package org.wildfly.extras.creaper.commands.elytron.realm; + +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; + +@RunWith(Arquillian.class) +public class AddCustomModifiableRealmOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_ADD_CUSTOM_MODIFIABLE_REALM_NAME = "CreaperTestAddCustomModifiableRealm"; + + @Test(expected = IllegalArgumentException.class) + public void addCustomModifiableRealm_nullName() throws Exception { + new AddCustomModifiableRealm.Builder(null) + .module("someModule") + .className("someClassName"); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAddCustomModifiableRealm_emptyName() throws Exception { + new AddCustomModifiableRealm.Builder("") + .module("someModule") + .className("someClassName"); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomModifiableRealm_noClassName() throws Exception { + new AddCustomModifiableRealm.Builder(TEST_ADD_CUSTOM_MODIFIABLE_REALM_NAME) + .module("someModule") + .build(); + fail("Creating command with no classname should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomModifiableRealm_emptyClassName() throws Exception { + new AddCustomModifiableRealm.Builder(TEST_ADD_CUSTOM_MODIFIABLE_REALM_NAME) + .module("someModule") + .className("") + .build(); + fail("Creating command with empty classname should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomModifiableRealm_noModule() throws Exception { + new AddCustomModifiableRealm.Builder(TEST_ADD_CUSTOM_MODIFIABLE_REALM_NAME) + .className("someClassName") + .build(); + fail("Creating command with no module should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomModifiableRealm_emptyModule() throws Exception { + new AddCustomModifiableRealm.Builder(TEST_ADD_CUSTOM_MODIFIABLE_REALM_NAME) + .module("") + .className("someClassName") + .build(); + fail("Creating command with empty module should throw exception"); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomRealmOfflineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomRealmOfflineTest.java new file mode 100644 index 00000000..a18f3289 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomRealmOfflineTest.java @@ -0,0 +1,34 @@ +package org.wildfly.extras.creaper.commands.elytron.realm; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractAddCustomOfflineTest; + + +@RunWith(Arquillian.class) +public class AddCustomRealmOfflineTest extends AbstractAddCustomOfflineTest { + + public String convertSubsystem(String subsystemString) { + return subsystemString.replaceAll(PARENT_TYPE, "security-realms") + .replaceAll(CUSTOM_TYPE, "custom-modifiable-realm") + .replaceAll(CUSTOM_NAME, getAddCustomName()) + .replaceAll(CLASS_NAME, getClassName()) + .replaceAll(MODULE_NAME, getModuleName()); + } + + public String getAddCustomName() { + return "customModifiableRealm"; + } + + public Object getBuilderObject(String name) { + return new AddCustomModifiableRealm.Builder(name); + } + + public String getModuleName() { + return "org.jboss.custommodifiablerealmimpl"; + } + + public String getClassName() { + return "SomeCustomModifiableRealm"; + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomRealmOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomRealmOnlineTest.java new file mode 100644 index 00000000..7c92ffb5 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddCustomRealmOnlineTest.java @@ -0,0 +1,65 @@ +package org.wildfly.extras.creaper.commands.elytron.realm; + +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; + +@RunWith(Arquillian.class) +public class AddCustomRealmOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_ADD_CUSTOM_REALM_NAME = "CreaperTestAddCustomRealm"; + + @Test(expected = IllegalArgumentException.class) + public void addCustomRealm_nullName() throws Exception { + new AddCustomRealm.Builder(null) + .module("someModule") + .className("someClassName"); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAddCustomRealm_emptyName() throws Exception { + new AddCustomRealm.Builder("") + .module("someModule") + .className("someClassName"); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomRealm_noClassName() throws Exception { + new AddCustomRealm.Builder(TEST_ADD_CUSTOM_REALM_NAME) + .module("someModule") + .build(); + fail("Creating command with no classname should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomRealm_emptyClassName() throws Exception { + new AddCustomRealm.Builder(TEST_ADD_CUSTOM_REALM_NAME) + .module("someModule") + .className("") + .build(); + fail("Creating command with empty classname should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomRealm_noModule() throws Exception { + new AddCustomRealm.Builder(TEST_ADD_CUSTOM_REALM_NAME) + .className("someClassName") + .build(); + fail("Creating command with no module should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addCustomRealm_emptyModule() throws Exception { + new AddCustomRealm.Builder(TEST_ADD_CUSTOM_REALM_NAME) + .module("") + .className("someClassName") + .build(); + fail("Creating command with empty module should throw exception"); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddFilesystemRealmOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddFilesystemRealmOnlineTest.java new file mode 100644 index 00000000..2ffe529c --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddFilesystemRealmOnlineTest.java @@ -0,0 +1,146 @@ +package org.wildfly.extras.creaper.commands.elytron.realm; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddFilesystemRealmOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_FILESYSTEM_REALM_NAME = "CreaperTestFilesystemRealm"; + private static final Address TEST_FILESYSTEM_REALM_ADDRESS = SUBSYSTEM_ADDRESS + .and("filesystem-realm", TEST_FILESYSTEM_REALM_NAME); + private static final String TEST_FILESYSTEM_REALM_NAME2 = "CreaperTestFilesystemRealm2"; + private static final Address TEST_FILESYSTEM_REALM_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("filesystem-realm", TEST_FILESYSTEM_REALM_NAME2); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_FILESYSTEM_REALM_ADDRESS); + ops.removeIfExists(TEST_FILESYSTEM_REALM_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleFilesystemRealm() throws Exception { + AddFilesystemRealm addFilesystemRealm = new AddFilesystemRealm.Builder(TEST_FILESYSTEM_REALM_NAME) + .path("/path/to/filesystem") + .build(); + + client.apply(addFilesystemRealm); + + assertTrue("Filesystem realm should be created", ops.exists(TEST_FILESYSTEM_REALM_ADDRESS)); + } + + @Test + public void addTwoSimpleFilesystemRealms() throws Exception { + AddFilesystemRealm addFilesystemRealm = new AddFilesystemRealm.Builder(TEST_FILESYSTEM_REALM_NAME) + .path("/path/to/filesystem") + .build(); + + AddFilesystemRealm addFilesystemRealm2 = new AddFilesystemRealm.Builder(TEST_FILESYSTEM_REALM_NAME2) + .path("/path/to/filesystem2") + .build(); + + client.apply(addFilesystemRealm); + client.apply(addFilesystemRealm2); + + assertTrue("Filesystem realm should be created", ops.exists(TEST_FILESYSTEM_REALM_ADDRESS)); + assertTrue("Second filesystem realm should be created", ops.exists(TEST_FILESYSTEM_REALM_ADDRESS2)); + } + + @Test + public void addFullFilesystemRealm() throws Exception { + AddFilesystemRealm addFilesystemRealm = new AddFilesystemRealm.Builder(TEST_FILESYSTEM_REALM_NAME) + .path("filesystem") + .relativeTo("jboss.server.config.dir") + .levels(5) + .encoded(false) + .build(); + + client.apply(addFilesystemRealm); + + assertTrue("Filesystem realm should be created", ops.exists(TEST_FILESYSTEM_REALM_ADDRESS)); + + checkAttribute(TEST_FILESYSTEM_REALM_ADDRESS, "path", "filesystem"); + checkAttribute(TEST_FILESYSTEM_REALM_ADDRESS, "relative-to", "jboss.server.config.dir"); + checkAttribute(TEST_FILESYSTEM_REALM_ADDRESS, "levels", "5"); + checkAttribute(TEST_FILESYSTEM_REALM_ADDRESS, "encoded", "false"); + } + + @Test(expected = CommandFailedException.class) + public void addExistFilesystemRealmNotAllowed() throws Exception { + AddFilesystemRealm addFilesystemRealm = new AddFilesystemRealm.Builder(TEST_FILESYSTEM_REALM_NAME) + .path("/path/to/filesystem") + .build(); + + AddFilesystemRealm addFilesystemRealm2 = new AddFilesystemRealm.Builder(TEST_FILESYSTEM_REALM_NAME) + .path("/path/to/second/filesystem") + .build(); + + client.apply(addFilesystemRealm); + assertTrue("Filesystem realm should be created", ops.exists(TEST_FILESYSTEM_REALM_ADDRESS)); + client.apply(addFilesystemRealm2); + fail("Filesystem realm CreaperTestFilesystemRealm already exists in configuration, exception should be thrown"); + + } + + @Test + public void addExistFilesystemRealmAllowed() throws Exception { + AddFilesystemRealm addFilesystemRealm = new AddFilesystemRealm.Builder(TEST_FILESYSTEM_REALM_NAME) + .path("/path/to/filesystem") + .build(); + + AddFilesystemRealm addFilesystemRealm2 = new AddFilesystemRealm.Builder(TEST_FILESYSTEM_REALM_NAME) + .path("/path/to/second/filesystem") + .replaceExisting() + .build(); + + client.apply(addFilesystemRealm); + assertTrue("Filesystem realm should be created", ops.exists(TEST_FILESYSTEM_REALM_ADDRESS)); + client.apply(addFilesystemRealm2); + assertTrue("Filesystem realm should be created", ops.exists(TEST_FILESYSTEM_REALM_ADDRESS)); + // check whether it was really rewritten + checkAttribute(TEST_FILESYSTEM_REALM_ADDRESS, "path", "/path/to/second/filesystem"); + } + + @Test(expected = IllegalArgumentException.class) + public void addFilesystemRealm_nullName() throws Exception { + new AddFilesystemRealm.Builder(null) + .path("/path/to/filesystem") + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addFilesystemRealm_emptyName() throws Exception { + new AddFilesystemRealm.Builder("") + .path("/path/to/filesystem") + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addFilesystemRealm_nullPath() throws Exception { + new AddFilesystemRealm.Builder(TEST_FILESYSTEM_REALM_NAME) + .path(null) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addFilesystemRealm_emptyPath() throws Exception { + new AddFilesystemRealm.Builder(TEST_FILESYSTEM_REALM_NAME) + .path("") + .build(); + fail("Creating command with empty name should throw exception"); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddIdentityRealmOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddIdentityRealmOnlineTest.java new file mode 100644 index 00000000..e306c900 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddIdentityRealmOnlineTest.java @@ -0,0 +1,144 @@ +package org.wildfly.extras.creaper.commands.elytron.realm; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +@RunWith(Arquillian.class) +public class AddIdentityRealmOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_IDENTITY_REALM_NAME = "CreaperTestIdentityRealm"; + private static final Address TEST_IDENTITY_REALM_ADDRESS = SUBSYSTEM_ADDRESS + .and("identity-realm", TEST_IDENTITY_REALM_NAME); + private static final String TEST_IDENTITY_REALM_NAME2 = "CreaperTestIdentityRealm2"; + private static final Address TEST_IDENTITY_REALM_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("identity-realm", TEST_IDENTITY_REALM_NAME2); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_IDENTITY_REALM_ADDRESS); + ops.removeIfExists(TEST_IDENTITY_REALM_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleIdentityRealm() throws Exception { + AddIdentityRealm addIdentityRealm = new AddIdentityRealm.Builder(TEST_IDENTITY_REALM_NAME) + .identity("someIdentity") + .build(); + + client.apply(addIdentityRealm); + + assertTrue("Identity realm should be created", ops.exists(TEST_IDENTITY_REALM_ADDRESS)); + } + + @Test + public void addTwoSimpleIdentityRealms() throws Exception { + AddIdentityRealm addIdentityRealm = new AddIdentityRealm.Builder(TEST_IDENTITY_REALM_NAME) + .identity("someIdentity") + .build(); + + AddIdentityRealm addIdentityRealm2 = new AddIdentityRealm.Builder(TEST_IDENTITY_REALM_NAME2) + .identity("someOtherIdentity") + .build(); + + client.apply(addIdentityRealm); + client.apply(addIdentityRealm2); + + assertTrue("Identity realm should be created", ops.exists(TEST_IDENTITY_REALM_ADDRESS)); + assertTrue("Second identity realm should be created", ops.exists(TEST_IDENTITY_REALM_ADDRESS2)); + } + + @Test + public void addFullIdentityRealm() throws Exception { + AddIdentityRealm addIdentityRealm = new AddIdentityRealm.Builder(TEST_IDENTITY_REALM_NAME) + .identity("someIdentity") + .attributeName("someAttribute") + .attributeValues("someValue", "someOtherValue") + .build(); + + client.apply(addIdentityRealm); + + assertTrue("Identity realm should be created", ops.exists(TEST_IDENTITY_REALM_ADDRESS)); + + checkAttribute(TEST_IDENTITY_REALM_ADDRESS, "identity", "someIdentity"); + checkAttribute(TEST_IDENTITY_REALM_ADDRESS, "attribute-name", "someAttribute"); + checkAttribute(TEST_IDENTITY_REALM_ADDRESS, "attribute-values[0]", "someValue"); + checkAttribute(TEST_IDENTITY_REALM_ADDRESS, "attribute-values[1]", "someOtherValue"); + } + + @Test(expected = CommandFailedException.class) + public void addExistIdentityRealmNotAllowed() throws Exception { + AddIdentityRealm addIdentityRealm = new AddIdentityRealm.Builder(TEST_IDENTITY_REALM_NAME) + .identity("someIdentity") + .build(); + + AddIdentityRealm addIdentityRealm2 = new AddIdentityRealm.Builder(TEST_IDENTITY_REALM_NAME) + .identity("someOtherIdentity") + .build(); + + client.apply(addIdentityRealm); + assertTrue("Identity realm should be created", ops.exists(TEST_IDENTITY_REALM_ADDRESS)); + client.apply(addIdentityRealm2); + fail("Identity realm CreaperTestIdentityRealm already exists in configuration, exception should be thrown"); + + } + + @Test + public void addExistIdentityRealmAllowed() throws Exception { + AddIdentityRealm addIdentityRealm = new AddIdentityRealm.Builder(TEST_IDENTITY_REALM_NAME) + .identity("someIdentity") + .build(); + + AddIdentityRealm addIdentityRealm2 = new AddIdentityRealm.Builder(TEST_IDENTITY_REALM_NAME) + .identity("someOtherIdentity") + .replaceExisting() + .build(); + + client.apply(addIdentityRealm); + assertTrue("Identity realm should be created", ops.exists(TEST_IDENTITY_REALM_ADDRESS)); + client.apply(addIdentityRealm2); + assertTrue("Identity realm should be created", ops.exists(TEST_IDENTITY_REALM_ADDRESS)); + // check whether it was really rewritten + checkAttribute(TEST_IDENTITY_REALM_ADDRESS, "identity", "someOtherIdentity"); + } + + @Test(expected = IllegalArgumentException.class) + public void addIdentityRealm_nullName() throws Exception { + new AddIdentityRealm.Builder(null) + .identity("someIdentity") + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addIdentityRealm_emptyName() throws Exception { + new AddIdentityRealm.Builder("") + .identity("someIdentity") + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addIdentityRealm_nullIdentity() throws Exception { + new AddIdentityRealm.Builder(TEST_IDENTITY_REALM_NAME) + .identity(null) + .build(); + fail("Creating command with null identity should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addIdentityRealm_emptyIdentity() throws Exception { + new AddIdentityRealm.Builder(TEST_IDENTITY_REALM_NAME) + .identity("") + .build(); + fail("Creating command with empty identity should throw exception"); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddJdbcRealmOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddJdbcRealmOnlineTest.java new file mode 100644 index 00000000..c45831c7 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddJdbcRealmOnlineTest.java @@ -0,0 +1,496 @@ +package org.wildfly.extras.creaper.commands.elytron.realm; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.commands.elytron.realm.AddJdbcRealm.AttributeMappingBuilder; +import org.wildfly.extras.creaper.commands.elytron.realm.AddJdbcRealm.BcryptMapperBuilder; +import org.wildfly.extras.creaper.commands.elytron.realm.AddJdbcRealm.ClearPasswordMapperBuilder; +import org.wildfly.extras.creaper.commands.elytron.realm.AddJdbcRealm.PrincipalQueryBuilder; +import org.wildfly.extras.creaper.commands.elytron.realm.AddJdbcRealm.SaltedSimpleDigestMapperBuilder; +import org.wildfly.extras.creaper.commands.elytron.realm.AddJdbcRealm.ScramMapperBuilder; +import org.wildfly.extras.creaper.commands.elytron.realm.AddJdbcRealm.SimpleDigestMapperBuilder; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddJdbcRealmOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_SALT_DIGEST_MD5 = "password-salt-digest-md5"; + private static final String TEST_SCRAM_ALGORITHM = "scram-sha-256"; + private static final String TEST_DIGEST_ALGORITHM = "simple-digest-md5"; + private static final Integer TEST_ITERATION_COUNT_INDEX = 3; + private static final Integer TEST_SALT_INDEX = 2; + private static final Integer TEST_PASSWORD_INDEX = 1; + private static final String TEST_JDBC_REALM_NAME = "CreaperTestJdbcRealm"; + private static final Address TEST_JDBC_REALM_ADDRESS = SUBSYSTEM_ADDRESS.and("jdbc-realm", TEST_JDBC_REALM_NAME); + private static final String TEST_JDBC_REALM_NAME2 = "CreaperTestJdbcRealm2"; + private static final Address TEST_JDBC_REALM_ADDRESS2 = SUBSYSTEM_ADDRESS.and("jdbc-realm", TEST_JDBC_REALM_NAME2); + private static final String TEST_SQL = "select * from users"; + private static final String TEST_SQL2 = "select * from users2"; + private static final String TEST_DS = "ExampleDS"; + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_JDBC_REALM_ADDRESS); + ops.removeIfExists(TEST_JDBC_REALM_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleJdbcRealm() throws Exception { + AddJdbcRealm addJdbcRealm = new AddJdbcRealm.Builder(TEST_JDBC_REALM_NAME) + .principalQueries(new PrincipalQueryBuilder() + .sql(TEST_SQL) + .dataSource(TEST_DS) + .build()) + .build(); + + client.apply(addJdbcRealm); + + assertTrue("Jdbc realm should be created", ops.exists(TEST_JDBC_REALM_ADDRESS)); + + } + + @Test + public void addTwoSimpleJdbcRealm() throws Exception { + AddJdbcRealm addJdbcRealm = new AddJdbcRealm.Builder(TEST_JDBC_REALM_NAME) + .principalQueries(new PrincipalQueryBuilder() + .sql(TEST_SQL) + .dataSource(TEST_DS) + .build()) + .build(); + + AddJdbcRealm addJdbcRealm2 = new AddJdbcRealm.Builder(TEST_JDBC_REALM_NAME2) + .principalQueries(new PrincipalQueryBuilder() + .sql(TEST_SQL) + .dataSource(TEST_DS) + .build()) + .build(); + + client.apply(addJdbcRealm); + client.apply(addJdbcRealm2); + + assertTrue("Jdbc realm should be created", ops.exists(TEST_JDBC_REALM_ADDRESS)); + assertTrue("Second jdbc realm should be created", ops.exists(TEST_JDBC_REALM_ADDRESS2)); + } + + @Test + public void addFullJdbcRealmClearPasswordMapper() throws Exception { + AddJdbcRealm addJdbcRealm = new AddJdbcRealm.Builder(TEST_JDBC_REALM_NAME) + .principalQueries(new PrincipalQueryBuilder() + .sql(TEST_SQL) + .dataSource(TEST_DS) + .clearPasswordMapper(new ClearPasswordMapperBuilder() + .passwordIndex(TEST_PASSWORD_INDEX) + .build()) + .attributeMapping(new AttributeMappingBuilder() + .index(1) + .to("groups") + .build(), + new AttributeMappingBuilder() + .index(2) + .to("roles") + .build()) + .build()) + .build(); + + client.apply(addJdbcRealm); + + assertTrue("Jdbc realm should be created", ops.exists(TEST_JDBC_REALM_ADDRESS)); + + checkAttribute(TEST_JDBC_REALM_ADDRESS, "principal-query[0].clear-password-mapper.password-index", + TEST_PASSWORD_INDEX.toString()); + checkAttribute(TEST_JDBC_REALM_ADDRESS, "principal-query[0].attribute-mapping[0].index", "1"); + checkAttribute(TEST_JDBC_REALM_ADDRESS, "principal-query[0].attribute-mapping[0].to", "groups"); + checkAttribute(TEST_JDBC_REALM_ADDRESS, "principal-query[0].attribute-mapping[1].index", "2"); + checkAttribute(TEST_JDBC_REALM_ADDRESS, "principal-query[0].attribute-mapping[1].to", "roles"); + } + + @Test + public void addBcryptMapper() throws Exception { + AddJdbcRealm addJdbcRealm = new AddJdbcRealm.Builder(TEST_JDBC_REALM_NAME) + .principalQueries(new PrincipalQueryBuilder() + .sql(TEST_SQL) + .dataSource(TEST_DS) + .bcryptMapper(new BcryptMapperBuilder() + .passwordIndex(TEST_PASSWORD_INDEX) + .saltIndex(TEST_SALT_INDEX) + .iterationCountIndex(TEST_ITERATION_COUNT_INDEX) + .build()) + .build()) + .build(); + + client.apply(addJdbcRealm); + + assertTrue("Jdbc realm should be created", ops.exists(TEST_JDBC_REALM_ADDRESS)); + + checkAttribute(TEST_JDBC_REALM_ADDRESS, "principal-query[0].bcrypt-mapper.password-index", + TEST_PASSWORD_INDEX.toString()); + checkAttribute(TEST_JDBC_REALM_ADDRESS, "principal-query[0].bcrypt-mapper.salt-index", + TEST_SALT_INDEX.toString()); + checkAttribute(TEST_JDBC_REALM_ADDRESS, "principal-query[0].bcrypt-mapper.iteration-count-index", + TEST_ITERATION_COUNT_INDEX.toString()); + } + + @Test + public void addSimpleDigestMapper() throws Exception { + AddJdbcRealm addJdbcRealm = new AddJdbcRealm.Builder(TEST_JDBC_REALM_NAME) + .principalQueries(new PrincipalQueryBuilder() + .sql(TEST_SQL) + .dataSource(TEST_DS) + .simpleDigestMapper(new SimpleDigestMapperBuilder() + .passwordIndex(TEST_PASSWORD_INDEX) + .algorithm(TEST_DIGEST_ALGORITHM) + .build()) + .build()) + .build(); + + client.apply(addJdbcRealm); + + assertTrue("Jdbc realm should be created", ops.exists(TEST_JDBC_REALM_ADDRESS)); + + checkAttribute(TEST_JDBC_REALM_ADDRESS, "principal-query[0].simple-digest-mapper.password-index", + TEST_PASSWORD_INDEX.toString()); + checkAttribute(TEST_JDBC_REALM_ADDRESS, "principal-query[0].simple-digest-mapper.algorithm", + TEST_DIGEST_ALGORITHM); + } + + @Test + public void addSaltedSimpleDigestMapper() throws Exception { + AddJdbcRealm addJdbcRealm = new AddJdbcRealm.Builder(TEST_JDBC_REALM_NAME) + .principalQueries(new PrincipalQueryBuilder() + .sql(TEST_SQL) + .dataSource(TEST_DS) + .saltedSimpleDigestMapper(new SaltedSimpleDigestMapperBuilder() + .passwordIndex(TEST_PASSWORD_INDEX) + .saltIndex(TEST_SALT_INDEX) + .algorithm(TEST_SALT_DIGEST_MD5) + .build()) + .build()) + .build(); + + client.apply(addJdbcRealm); + + assertTrue("Jdbc realm should be created", ops.exists(TEST_JDBC_REALM_ADDRESS)); + + checkAttribute(TEST_JDBC_REALM_ADDRESS, "principal-query[0].salted-simple-digest-mapper.password-index", + TEST_PASSWORD_INDEX.toString()); + checkAttribute(TEST_JDBC_REALM_ADDRESS, "principal-query[0].salted-simple-digest-mapper.salt-index", + TEST_SALT_INDEX.toString()); + checkAttribute(TEST_JDBC_REALM_ADDRESS, "principal-query[0].salted-simple-digest-mapper.algorithm", + TEST_SALT_DIGEST_MD5); + } + + @Test + public void addFullJdbcRealmScramMapper() throws Exception { + AddJdbcRealm addJdbcRealm = new AddJdbcRealm.Builder(TEST_JDBC_REALM_NAME) + .principalQueries(new PrincipalQueryBuilder() + .sql(TEST_SQL) + .dataSource(TEST_DS) + .scramMapper(new ScramMapperBuilder() + .passwordIndex(TEST_PASSWORD_INDEX) + .saltIndex(TEST_SALT_INDEX) + .iterationCountIndex(TEST_ITERATION_COUNT_INDEX) + .algorithm(TEST_SCRAM_ALGORITHM) + .build()) + .build()) + .build(); + + client.apply(addJdbcRealm); + + assertTrue("Jdbc realm should be created", ops.exists(TEST_JDBC_REALM_ADDRESS)); + + checkAttribute(TEST_JDBC_REALM_ADDRESS, "principal-query[0].scram-mapper.password-index", + TEST_PASSWORD_INDEX.toString()); + checkAttribute(TEST_JDBC_REALM_ADDRESS, "principal-query[0].scram-mapper.salt-index", + TEST_SALT_INDEX.toString()); + checkAttribute(TEST_JDBC_REALM_ADDRESS, "principal-query[0].scram-mapper.iteration-count-index", + TEST_ITERATION_COUNT_INDEX.toString()); + checkAttribute(TEST_JDBC_REALM_ADDRESS, "principal-query[0].scram-mapper.algorithm", + TEST_SCRAM_ALGORITHM); + } + + @Test(expected = CommandFailedException.class) + public void addJdbcRealmNotAllowed() throws Exception { + + AddJdbcRealm addJdbcRealm = new AddJdbcRealm.Builder(TEST_JDBC_REALM_NAME) + .principalQueries(new PrincipalQueryBuilder() + .sql(TEST_SQL) + .dataSource(TEST_DS) + .build()) + .build(); + + AddJdbcRealm addJdbcRealm2 = new AddJdbcRealm.Builder(TEST_JDBC_REALM_NAME) + .principalQueries(new PrincipalQueryBuilder() + .sql(TEST_SQL) + .dataSource(TEST_DS) + .build()) + .build(); + + client.apply(addJdbcRealm); + assertTrue("Jdbc realm should be created", ops.exists(TEST_JDBC_REALM_ADDRESS)); + client.apply(addJdbcRealm2); + fail("Jdbc realm" + TEST_JDBC_REALM_NAME + " already exists in configuration, exception should be thrown"); + } + + @Test() + public void addJdbcRealmAllowed() throws Exception { + + AddJdbcRealm addJdbcRealm = new AddJdbcRealm.Builder(TEST_JDBC_REALM_NAME) + .principalQueries(new PrincipalQueryBuilder() + .sql(TEST_SQL) + .dataSource(TEST_DS) + .build()) + .build(); + + AddJdbcRealm addJdbcRealm2 = new AddJdbcRealm.Builder(TEST_JDBC_REALM_NAME) + .principalQueries(new PrincipalQueryBuilder() + .sql(TEST_SQL2) + .dataSource(TEST_DS) + .build()) + .replaceExisting() + .build(); + + client.apply(addJdbcRealm); + assertTrue("Jdbc realm should be created", ops.exists(TEST_JDBC_REALM_ADDRESS)); + client.apply(addJdbcRealm2); + assertTrue("Jdbc realm should be created", ops.exists(TEST_JDBC_REALM_ADDRESS)); + // check whether it was really rewritten + checkAttribute(TEST_JDBC_REALM_ADDRESS, "principal-query[0].sql", TEST_SQL2); + + } + + @Test(expected = IllegalArgumentException.class) + public void addJdbcRealm_nullName() throws Exception { + new AddJdbcRealm.Builder(null) + .principalQueries(new PrincipalQueryBuilder() + .sql(TEST_SQL) + .dataSource(TEST_DS) + .build()) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addJdbcRealm_emptyName() throws Exception { + new AddJdbcRealm.Builder("") + .principalQueries(new PrincipalQueryBuilder() + .sql(TEST_SQL) + .dataSource(TEST_DS) + .build()) + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addJdbcRealm_nullDataSource() throws Exception { + new AddJdbcRealm.Builder(TEST_JDBC_REALM_NAME) + .principalQueries(new PrincipalQueryBuilder() + .sql(TEST_SQL) + .dataSource(null) + .build()) + .build(); + fail("Creating command with null data source should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addJdbcRealm_emptyDataSource() throws Exception { + new AddJdbcRealm.Builder(TEST_JDBC_REALM_NAME) + .principalQueries(new PrincipalQueryBuilder() + .sql(TEST_SQL) + .dataSource("") + .build()) + .build(); + fail("Creating command with empty data source should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAttributeMapping_nullIndex() throws Exception { + new AddJdbcRealm.Builder(TEST_JDBC_REALM_NAME) + .principalQueries(new PrincipalQueryBuilder() + .sql(TEST_SQL) + .dataSource(TEST_DS) + .attributeMapping(new AttributeMappingBuilder() + .index(null) + .to("groups") + .build()) + .build()) + .build(); + fail("Creating command with null index should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAttributeMapping_nullTo() throws Exception { + new AddJdbcRealm.Builder(TEST_JDBC_REALM_NAME) + .principalQueries(new PrincipalQueryBuilder() + .sql(TEST_SQL) + .dataSource(TEST_DS) + .attributeMapping(new AttributeMappingBuilder() + .index(0) + .to(null) + .build()) + .build()) + .build(); + fail("Creating command with null \"to\" should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addClearPasswordMapper_nullPasswordIndex() throws Exception { + new AddJdbcRealm.Builder(TEST_JDBC_REALM_NAME) + .principalQueries(new PrincipalQueryBuilder() + .sql(TEST_SQL) + .dataSource(TEST_DS) + .clearPasswordMapper(new ClearPasswordMapperBuilder() + .passwordIndex(null) + .build()) + .build()) + .build(); + fail("Creating command with null password-index should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addBcryptMapper_nullPasswordIndex() throws Exception { + new AddJdbcRealm.Builder(TEST_JDBC_REALM_NAME) + .principalQueries(new PrincipalQueryBuilder() + .sql(TEST_SQL) + .dataSource(TEST_DS) + .bcryptMapper(new BcryptMapperBuilder() + .passwordIndex(null) + .saltIndex(TEST_SALT_INDEX) + .iterationCountIndex(TEST_ITERATION_COUNT_INDEX) + .build()) + .build()) + .build(); + fail("Creating command with null password-index should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addBcryptMapper_nullSaltIndex() throws Exception { + new AddJdbcRealm.Builder(TEST_JDBC_REALM_NAME) + .principalQueries(new PrincipalQueryBuilder() + .sql(TEST_SQL) + .dataSource(TEST_DS) + .bcryptMapper(new BcryptMapperBuilder() + .passwordIndex(TEST_PASSWORD_INDEX) + .saltIndex(null) + .iterationCountIndex(TEST_ITERATION_COUNT_INDEX) + .build()) + .build()) + .build(); + fail("Creating command with null salt index should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addBcryptMapper_nullIterationCountIndex() throws Exception { + new AddJdbcRealm.Builder(TEST_JDBC_REALM_NAME) + .principalQueries(new PrincipalQueryBuilder() + .sql(TEST_SQL) + .dataSource(TEST_DS) + .bcryptMapper(new BcryptMapperBuilder() + .passwordIndex(TEST_PASSWORD_INDEX) + .saltIndex(TEST_SALT_INDEX) + .iterationCountIndex(null) + .build()) + .build()) + .build(); + fail("Creating command with null iteration count index should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSimpleDigestMapper_nullPasswordIndex() throws Exception { + new AddJdbcRealm.Builder(TEST_JDBC_REALM_NAME) + .principalQueries(new PrincipalQueryBuilder() + .sql(TEST_SQL) + .dataSource(TEST_DS) + .simpleDigestMapper(new SimpleDigestMapperBuilder() + .passwordIndex(null) + .build()) + .build()) + .build(); + fail("Creating command with null password index should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSaltedSimpleDigestMapper_nullPasswordIndex() throws Exception { + new AddJdbcRealm.Builder(TEST_JDBC_REALM_NAME) + .principalQueries(new PrincipalQueryBuilder() + .sql(TEST_SQL) + .dataSource(TEST_DS) + .saltedSimpleDigestMapper(new SaltedSimpleDigestMapperBuilder() + .passwordIndex(null) + .saltIndex(TEST_SALT_INDEX) + .build()) + .build()) + .build(); + fail("Creating command with null password index should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSaltedSimpleDigestMapper_nullSaltIndex() throws Exception { + new AddJdbcRealm.Builder(TEST_JDBC_REALM_NAME) + .principalQueries(new PrincipalQueryBuilder() + .sql(TEST_SQL) + .dataSource(TEST_DS) + .saltedSimpleDigestMapper(new SaltedSimpleDigestMapperBuilder() + .passwordIndex(TEST_PASSWORD_INDEX) + .saltIndex(null) + .build()) + .build()) + .build(); + fail("Creating command with null salt index should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addScramMapper_nullPasswordIndex() throws Exception { + new AddJdbcRealm.Builder(TEST_JDBC_REALM_NAME) + .principalQueries(new PrincipalQueryBuilder() + .sql(TEST_SQL) + .dataSource(TEST_DS) + .scramMapper(new ScramMapperBuilder() + .passwordIndex(null) + .saltIndex(TEST_SALT_INDEX) + .iterationCountIndex(TEST_ITERATION_COUNT_INDEX) + .build()) + .build()) + .build(); + fail("Creating command with null password index should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addScramMapper_nullSaltIndex() throws Exception { + new AddJdbcRealm.Builder(TEST_JDBC_REALM_NAME) + .principalQueries(new PrincipalQueryBuilder() + .sql(TEST_SQL) + .dataSource(TEST_DS) + .scramMapper(new ScramMapperBuilder() + .passwordIndex(TEST_PASSWORD_INDEX) + .saltIndex(null) + .iterationCountIndex(TEST_ITERATION_COUNT_INDEX) + .build()) + .build()) + .build(); + fail("Creating command with null salt index should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addScramMapper_nullIterationCountIndex() throws Exception { + new AddJdbcRealm.Builder(TEST_JDBC_REALM_NAME) + .principalQueries(new PrincipalQueryBuilder() + .sql(TEST_SQL) + .dataSource(TEST_DS) + .scramMapper(new ScramMapperBuilder() + .passwordIndex(TEST_PASSWORD_INDEX) + .saltIndex(TEST_SALT_INDEX) + .iterationCountIndex(null) + .build()) + .build()) + .build(); + fail("Creating command with null iteration count index should throw exception"); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddKeyStoreRealmOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddKeyStoreRealmOnlineTest.java new file mode 100644 index 00000000..279a1165 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddKeyStoreRealmOnlineTest.java @@ -0,0 +1,131 @@ +package org.wildfly.extras.creaper.commands.elytron.realm; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.commands.elytron.CredentialRef; +import org.wildfly.extras.creaper.commands.elytron.tls.AddKeyStore; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + + +@RunWith(Arquillian.class) +public class AddKeyStoreRealmOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_ADD_KEY_STORE_REALM_NAME = "CreaperTestAddKeyStoreRealm"; + private static final Address TEST_ADD_KEY_STORE_REALM_ADDRESS = SUBSYSTEM_ADDRESS.and("key-store-realm", + TEST_ADD_KEY_STORE_REALM_NAME); + private static final String TEST_ADD_KEY_STORE_REALM_NAME2 = "CreaperTestAddKeyStoreRealm2"; + private static final Address TEST_ADD_KEY_STORE_REALM_ADDRESS2 = SUBSYSTEM_ADDRESS.and("key-store-realm", + TEST_ADD_KEY_STORE_REALM_NAME2); + private static final String TEST_DEFAULT_KEYSTORE_NAME = "CreaperTestKeyStore"; + private static final String TEST_KEY_STORE_TYPE = "JKS"; + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_ADD_KEY_STORE_REALM_ADDRESS); + ops.removeIfExists(TEST_ADD_KEY_STORE_REALM_ADDRESS2); + removeAllElytronChildrenType("key-store"); + + administration.reloadIfRequired(); + } + + @Test + public void addKeyStoreRealm() throws Exception { + addDefaultKeyStore(); + + AddKeyStoreRealm addAddPrefixRoleMapper = new AddKeyStoreRealm.Builder(TEST_ADD_KEY_STORE_REALM_NAME) + .keyStore(TEST_DEFAULT_KEYSTORE_NAME) + .build(); + + client.apply(addAddPrefixRoleMapper); + + assertTrue("Add key-store-realm should be created", ops.exists(TEST_ADD_KEY_STORE_REALM_ADDRESS)); + } + + @Test + public void addKeyStoreRealms() throws Exception { + addKeyStore("keyStore1"); + addKeyStore("keyStore2"); + + AddKeyStoreRealm addKeyStoreRealm1 = new AddKeyStoreRealm.Builder(TEST_ADD_KEY_STORE_REALM_NAME) + .keyStore("keyStore1") + .build(); + + AddKeyStoreRealm addKeyStoreRealm2 = new AddKeyStoreRealm.Builder(TEST_ADD_KEY_STORE_REALM_NAME2) + .keyStore("keyStore2") + .build(); + + client.apply(addKeyStoreRealm1); + client.apply(addKeyStoreRealm2); + + assertTrue("Add key-store-realm should be created", ops.exists(TEST_ADD_KEY_STORE_REALM_ADDRESS)); + assertTrue("Second key-store-realm should be created", ops.exists(TEST_ADD_KEY_STORE_REALM_ADDRESS2)); + + checkAttribute(TEST_ADD_KEY_STORE_REALM_ADDRESS, "key-store", "keyStore1"); + checkAttribute(TEST_ADD_KEY_STORE_REALM_ADDRESS2, "key-store", "keyStore2"); + + administration.reload(); + + checkAttribute(TEST_ADD_KEY_STORE_REALM_ADDRESS, "key-store", "keyStore1"); + checkAttribute(TEST_ADD_KEY_STORE_REALM_ADDRESS2, "key-store", "keyStore2"); + } + + @Test(expected = CommandFailedException.class) + public void addDuplicateKeyStoreRealmNotAllowed() throws Exception { + addDefaultKeyStore(); + + AddKeyStoreRealm addKeyStoreRealm = new AddKeyStoreRealm.Builder(TEST_ADD_KEY_STORE_REALM_NAME) + .keyStore(TEST_DEFAULT_KEYSTORE_NAME) + .build(); + + client.apply(addKeyStoreRealm); + assertTrue("Add key-store-realm should be created", ops.exists(TEST_ADD_KEY_STORE_REALM_ADDRESS)); + client.apply(addKeyStoreRealm); + fail("Add key-store-realm " + TEST_ADD_KEY_STORE_REALM_NAME + + " already exists in configuration, exception should be thrown"); + } + + @Test(expected = IllegalArgumentException.class) + public void addKeyStoreReal_nullName() throws Exception { + new AddKeyStoreRealm.Builder(null); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addKeyStoreReal_emptyName() throws Exception { + new AddKeyStoreRealm.Builder(""); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addKeyStoreReal_noKeyStore() throws Exception { + new AddKeyStoreRealm.Builder(TEST_ADD_KEY_STORE_REALM_NAME).build(); + fail("Creating command with no key-store should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addKeyStoreReal_emptykeyStore() throws Exception { + new AddKeyStoreRealm.Builder(TEST_ADD_KEY_STORE_REALM_NAME).keyStore("").build(); + fail("Creating command with empty key-store should throw exception"); + } + + private void addDefaultKeyStore() throws CommandFailedException { + addKeyStore(TEST_DEFAULT_KEYSTORE_NAME); + } + + private void addKeyStore(String keyStoreName) throws CommandFailedException { + AddKeyStore addKeyStore = new AddKeyStore.Builder(keyStoreName) + .type(TEST_KEY_STORE_TYPE) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("test-Password") + .build()) + .build(); + client.apply(addKeyStore); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddLdapRealmOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddLdapRealmOnlineTest.java new file mode 100644 index 00000000..d074c47c --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddLdapRealmOnlineTest.java @@ -0,0 +1,533 @@ +package org.wildfly.extras.creaper.commands.elytron.realm; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.commands.elytron.dircontext.AddDirContext; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public final class AddLdapRealmOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_LDAP_REALM_NAME = "CreaperTestLdapRealm"; + private static final Address TEST_LDAP_REALM_ADDRESS = SUBSYSTEM_ADDRESS + .and("ldap-realm", TEST_LDAP_REALM_NAME); + private static final String TEST_LDAP_REALM_NAME2 = "CreaperTestLdapRealm2"; + private static final Address TEST_LDAP_REALM_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("ldap-realm", TEST_LDAP_REALM_NAME2); + + private static final String TEST_DIR_CONTEXT_NAME = "CreaperTestDirContext"; + private static final Address TEST_DIR_CONTEXT_ADDRESS = SUBSYSTEM_ADDRESS + .and("dir-context", TEST_DIR_CONTEXT_NAME); + private final AddDirContext addDirContext = new AddDirContext.Builder(TEST_DIR_CONTEXT_NAME) + .url("localhost") + .authenticationLevel(AddDirContext.AuthenticationLevel.NONE) + .build(); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_LDAP_REALM_ADDRESS); + ops.removeIfExists(TEST_LDAP_REALM_ADDRESS2); + ops.removeIfExists(TEST_DIR_CONTEXT_ADDRESS); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleLdapRealm() throws Exception { + client.apply(addDirContext); + + AddLdapRealm addLdapRealm = new AddLdapRealm.Builder(TEST_LDAP_REALM_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .identityMapping(new AddLdapRealm.IdentityMappingBuilder() + .rdnIdentifier("someId") + .build()) + .build(); + + client.apply(addLdapRealm); + + assertTrue("Ldap realm should be created", ops.exists(TEST_LDAP_REALM_ADDRESS)); + } + + @Test + public void addTwoSimpleLdapRealms() throws Exception { + client.apply(addDirContext); + + AddLdapRealm addLdapRealm = new AddLdapRealm.Builder(TEST_LDAP_REALM_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .identityMapping(new AddLdapRealm.IdentityMappingBuilder() + .rdnIdentifier("someId") + .build()) + .build(); + + AddLdapRealm addLdapRealm2 = new AddLdapRealm.Builder(TEST_LDAP_REALM_NAME2) + .dirContext(TEST_DIR_CONTEXT_NAME) + .identityMapping(new AddLdapRealm.IdentityMappingBuilder() + .rdnIdentifier("someId") + .build()) + .build(); + + client.apply(addLdapRealm); + client.apply(addLdapRealm2); + + assertTrue("Ldap realm should be created", ops.exists(TEST_LDAP_REALM_ADDRESS)); + assertTrue("Second ldap realm should be created", ops.exists(TEST_LDAP_REALM_ADDRESS2)); + } + + @Test + public void addFullLdapRealm() throws Exception { + client.apply(addDirContext); + + AddLdapRealm addLdapRealm = new AddLdapRealm.Builder(TEST_LDAP_REALM_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .directVerification(false) + .allowBlankPassword(true) + .identityMapping(new AddLdapRealm.IdentityMappingBuilder() + .rdnIdentifier("someId") + .searchBaseDn("someSearchBaseDn") + .useRecursiveSearch(true) + .filterName("someFilterName") + .iteratorFilter("someIteratorFilter") + .newIdentityParentDn("DN=someDn") + .addAttributeMappings(new AddLdapRealm.AttributeMappingBuilder() + .from("someAttributeFrom") + .to("someAttributeTo") + .extractRdn("someAttributeAsRdn") + .roleRecursion(0) + .roleRecursionName("someRoleRecursionName1") + .reference("someReference1") + .build(), + new AddLdapRealm.AttributeMappingBuilder() + .from("someAttributeFrom2") + .to("someAttributeTo2") + .filter("someAttributeFilter2") + .filterBaseDn("someAttributeFilterBaseDn2") + .extractRdn("someAttributeAsRdn2") + .searchRecursive(false) + .roleRecursion(5) + .roleRecursionName("someRoleRecursionName2") + .build()) + .userPasswordMapper(new AddLdapRealm.UserPasswordMapperBuilder() + .from("someUserPasswordFrom") + .writable(true) + .verifiable(true) + .build()) + .otpCredentialMapper(new AddLdapRealm.OtpCredentialMapperBuilder() + .algorithmFrom("someAlgorithmFrom") + .hashFrom("someHashFrom") + .seedFrom("someSeedFrom") + .sequenceFrom("someSequenceFrom") + .build()) + .x509CredentialMapper(new AddLdapRealm.X509CredentialMapperBuilder() + .digestFrom("someDigestFrom") + .digestAlgorithm("someDigestAlgorithm") + .certificateFrom("someCertificateFrom") + .serialNumberFrom("someSerialNumberFrom") + .subjectDnFrom("someSubjectDnFrom") + .build()) + .addNewIdentityAttributes(new AddLdapRealm.NewIdentityAttributesBuilder() + .name("someName") + .addValues("someValue1", "someValue2") + .build(), + new AddLdapRealm.NewIdentityAttributesBuilder() + .name("someName2") + .addValues("someValue3") + .build()) + .build()) + .build(); + + client.apply(addLdapRealm); + + assertTrue("Ldap realm should be created", ops.exists(TEST_LDAP_REALM_ADDRESS)); + + checkAttribute("dir-context", TEST_DIR_CONTEXT_NAME); + checkAttribute("direct-verification", "false"); + checkAttribute("allow-blank-password", "true"); + checkAttribute("identity-mapping.rdn-identifier", "someId"); + checkAttribute("identity-mapping.search-base-dn", "someSearchBaseDn"); + checkAttribute("identity-mapping.use-recursive-search", "true"); + checkAttribute("identity-mapping.filter-name", "someFilterName"); + checkAttribute("identity-mapping.iterator-filter", "someIteratorFilter"); + checkAttribute("identity-mapping.new-identity-parent-dn", "DN=someDn"); + + checkAttribute("identity-mapping.attribute-mapping[0].from", "someAttributeFrom"); + checkAttribute("identity-mapping.attribute-mapping[0].to", "someAttributeTo"); + checkAttribute("identity-mapping.attribute-mapping[0].extract-rdn", "someAttributeAsRdn"); + checkAttribute("identity-mapping.attribute-mapping[0].role-recursion", "0"); + checkAttribute("identity-mapping.attribute-mapping[0].role-recursion-name", "someRoleRecursionName1"); + checkAttribute("identity-mapping.attribute-mapping[0].reference", "someReference1"); + checkAttribute("identity-mapping.attribute-mapping[1].from", "someAttributeFrom2"); + checkAttribute("identity-mapping.attribute-mapping[1].to", "someAttributeTo2"); + checkAttribute("identity-mapping.attribute-mapping[1].filter", "someAttributeFilter2"); + checkAttribute("identity-mapping.attribute-mapping[1].filter-base-dn", "someAttributeFilterBaseDn2"); + checkAttribute("identity-mapping.attribute-mapping[1].extract-rdn", "someAttributeAsRdn2"); + checkAttribute("identity-mapping.attribute-mapping[1].search-recursive", "false"); + checkAttribute("identity-mapping.attribute-mapping[1].role-recursion", "5"); + checkAttribute("identity-mapping.attribute-mapping[1].role-recursion-name", "someRoleRecursionName2"); + + checkAttribute("identity-mapping.user-password-mapper.from", "someUserPasswordFrom"); + checkAttribute("identity-mapping.user-password-mapper.writable", "true"); + checkAttribute("identity-mapping.user-password-mapper.verifiable", "true"); + + checkAttribute("identity-mapping.otp-credential-mapper.algorithm-from", "someAlgorithmFrom"); + checkAttribute("identity-mapping.otp-credential-mapper.hash-from", "someHashFrom"); + checkAttribute("identity-mapping.otp-credential-mapper.seed-from", "someSeedFrom"); + checkAttribute("identity-mapping.otp-credential-mapper.sequence-from", "someSequenceFrom"); + + checkAttribute("identity-mapping.x509-credential-mapper.digest-from", "someDigestFrom"); + checkAttribute("identity-mapping.x509-credential-mapper.digest-algorithm", "someDigestAlgorithm"); + checkAttribute("identity-mapping.x509-credential-mapper.certificate-from", "someCertificateFrom"); + checkAttribute("identity-mapping.x509-credential-mapper.serial-number-from", "someSerialNumberFrom"); + checkAttribute("identity-mapping.x509-credential-mapper.subject-dn-from", "someSubjectDnFrom"); + + checkAttribute("identity-mapping.new-identity-attributes[0].name", "someName"); + checkAttribute("identity-mapping.new-identity-attributes[0].value[0]", "someValue1"); + checkAttribute("identity-mapping.new-identity-attributes[0].value[1]", "someValue2"); + checkAttribute("identity-mapping.new-identity-attributes[1].name", "someName2"); + checkAttribute("identity-mapping.new-identity-attributes[1].value[0]", "someValue3"); + } + + @Test(expected = CommandFailedException.class) + public void addExistLdapRealmNotAllowed() throws Exception { + client.apply(addDirContext); + + AddLdapRealm addLdapRealm = new AddLdapRealm.Builder(TEST_LDAP_REALM_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .identityMapping(new AddLdapRealm.IdentityMappingBuilder() + .rdnIdentifier("someId") + .build()) + .build(); + + AddLdapRealm addLdapRealm2 = new AddLdapRealm.Builder(TEST_LDAP_REALM_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .identityMapping(new AddLdapRealm.IdentityMappingBuilder() + .rdnIdentifier("someId2") + .build()) + .build(); + + client.apply(addLdapRealm); + assertTrue("Ldap realm should be created", ops.exists(TEST_LDAP_REALM_ADDRESS)); + client.apply(addLdapRealm2); + fail("Ldap realm CreaperTestLdapRealm already exists in configuration, exception should be thrown"); + + } + + @Test + public void addExistLdapRealmAllowed() throws Exception { + client.apply(addDirContext); + + AddLdapRealm addLdapRealm = new AddLdapRealm.Builder(TEST_LDAP_REALM_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .identityMapping(new AddLdapRealm.IdentityMappingBuilder() + .rdnIdentifier("someId") + .build()) + .build(); + + AddLdapRealm addLdapRealm2 = new AddLdapRealm.Builder(TEST_LDAP_REALM_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .identityMapping(new AddLdapRealm.IdentityMappingBuilder() + .rdnIdentifier("someId2") + .build()) + .replaceExisting() + .build(); + + client.apply(addLdapRealm); + assertTrue("Ldap realm should be created", ops.exists(TEST_LDAP_REALM_ADDRESS)); + client.apply(addLdapRealm2); + assertTrue("Ldap realm should be created", ops.exists(TEST_LDAP_REALM_ADDRESS)); + // check whether it was really rewritten + checkAttribute("identity-mapping.rdn-identifier", "someId2"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapRealm_nullName() throws Exception { + new AddLdapRealm.Builder(null) + .dirContext(TEST_DIR_CONTEXT_NAME) + .identityMapping(new AddLdapRealm.IdentityMappingBuilder() + .rdnIdentifier("someId") + .build()) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapRealm_emptyName() throws Exception { + new AddLdapRealm.Builder("") + .dirContext(TEST_DIR_CONTEXT_NAME) + .identityMapping(new AddLdapRealm.IdentityMappingBuilder() + .rdnIdentifier("someId") + .build()) + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapRealm_nullDirContext() throws Exception { + new AddLdapRealm.Builder(TEST_LDAP_REALM_NAME) + .dirContext(null) + .identityMapping(new AddLdapRealm.IdentityMappingBuilder() + .rdnIdentifier("someId") + .build()) + .build(); + fail("Creating command with null dir-context should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapRealm_emptyDirContext() throws Exception { + new AddLdapRealm.Builder(TEST_LDAP_REALM_NAME) + .dirContext("") + .identityMapping(new AddLdapRealm.IdentityMappingBuilder() + .rdnIdentifier("someId") + .build()) + .build(); + fail("Creating command with empty dir-context should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapRealm_nullIdentityMapping() throws Exception { + new AddLdapRealm.Builder(TEST_LDAP_REALM_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .identityMapping(null) + .build(); + fail("Creating command with null identity-mapping should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapRealm_nullRdnIdentifier_identityMapping() throws Exception { + new AddLdapRealm.Builder(TEST_LDAP_REALM_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .identityMapping(new AddLdapRealm.IdentityMappingBuilder() + .rdnIdentifier(null) + .build()) + .build(); + fail("Creating command with null rdn-identifier of identity-mapping should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapRealm_emptyRdnIdentifier_identityMapping() throws Exception { + new AddLdapRealm.Builder(TEST_LDAP_REALM_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .identityMapping(new AddLdapRealm.IdentityMappingBuilder() + .rdnIdentifier("") + .build()) + .build(); + fail("Creating command with empty rdn-identifier of identity-mapping should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapRealm_nullFrom_userPasswordMapper() throws Exception { + new AddLdapRealm.Builder(TEST_LDAP_REALM_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .identityMapping(new AddLdapRealm.IdentityMappingBuilder() + .rdnIdentifier("someId") + .userPasswordMapper(new AddLdapRealm.UserPasswordMapperBuilder() + .from(null) + .build()) + .build()) + .build(); + fail("Creating command with null identity-mapping.user-password-mapper.from should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapRealm_emptyFrom_userPasswordMapper() throws Exception { + new AddLdapRealm.Builder(TEST_LDAP_REALM_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .identityMapping(new AddLdapRealm.IdentityMappingBuilder() + .rdnIdentifier("someId") + .userPasswordMapper(new AddLdapRealm.UserPasswordMapperBuilder() + .from("") + .build()) + .build()) + .build(); + fail("Creating command with empty identity-mapping.user-password-mapper.from should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapRealm_nullAlgorithmFrom_otpCredentialMapper() throws Exception { + new AddLdapRealm.Builder(TEST_LDAP_REALM_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .identityMapping(new AddLdapRealm.IdentityMappingBuilder() + .rdnIdentifier("someId") + .otpCredentialMapper(new AddLdapRealm.OtpCredentialMapperBuilder() + .algorithmFrom(null) + .hashFrom("hashFrom") + .seedFrom("seedFrom") + .sequenceFrom("sequenceFrom") + .build()) + .build()) + .build(); + fail("Creating command with null identity-mapping.otp-credential-mapper.algorithm-from should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapRealm_emptyAlgorithmFrom_otpCredentialMapper() throws Exception { + new AddLdapRealm.Builder(TEST_LDAP_REALM_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .identityMapping(new AddLdapRealm.IdentityMappingBuilder() + .rdnIdentifier("someId") + .otpCredentialMapper(new AddLdapRealm.OtpCredentialMapperBuilder() + .algorithmFrom("") + .hashFrom("hashFrom") + .seedFrom("seedFrom") + .sequenceFrom("sequenceFrom") + .build()) + .build()) + .build(); + fail("Creating command with empty identity-mapping.otp-credential-mapper.algorithm-from should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapRealm_nullHashFrom_otpCredentialMapper() throws Exception { + new AddLdapRealm.Builder(TEST_LDAP_REALM_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .identityMapping(new AddLdapRealm.IdentityMappingBuilder() + .rdnIdentifier("someId") + .otpCredentialMapper(new AddLdapRealm.OtpCredentialMapperBuilder() + .algorithmFrom("algFrom") + .hashFrom(null) + .seedFrom("seedFrom") + .sequenceFrom("sequenceFrom") + .build()) + .build()) + .build(); + fail("Creating command with null identity-mapping.otp-credential-mapper.hash-from should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapRealm_emptyHashFrom_otpCredentialMapper() throws Exception { + new AddLdapRealm.Builder(TEST_LDAP_REALM_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .identityMapping(new AddLdapRealm.IdentityMappingBuilder() + .rdnIdentifier("someId") + .otpCredentialMapper(new AddLdapRealm.OtpCredentialMapperBuilder() + .algorithmFrom("algFrom") + .hashFrom("") + .seedFrom("seedFrom") + .sequenceFrom("sequenceFrom") + .build()) + .build()) + .build(); + fail("Creating command with empty identity-mapping.otp-credential-mapper.hash-from should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapRealm_nullSeedFrom_otpCredentialMapper() throws Exception { + new AddLdapRealm.Builder(TEST_LDAP_REALM_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .identityMapping(new AddLdapRealm.IdentityMappingBuilder() + .rdnIdentifier("someId") + .otpCredentialMapper(new AddLdapRealm.OtpCredentialMapperBuilder() + .algorithmFrom("algFrom") + .hashFrom("hashFrom") + .seedFrom(null) + .sequenceFrom("sequenceFrom") + .build()) + .build()) + .build(); + fail("Creating command with null identity-mapping.otp-credential-mapper.seed-from should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapRealm_emptySeedFrom_otpCredentialMapper() throws Exception { + new AddLdapRealm.Builder(TEST_LDAP_REALM_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .identityMapping(new AddLdapRealm.IdentityMappingBuilder() + .rdnIdentifier("someId") + .otpCredentialMapper(new AddLdapRealm.OtpCredentialMapperBuilder() + .algorithmFrom("algFrom") + .hashFrom("hashFrom") + .seedFrom("") + .sequenceFrom("sequenceFrom") + .build()) + .build()) + .build(); + fail("Creating command with empty identity-mapping.otp-credential-mapper.seed-from should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapRealm_nullSequenceFrom_otpCredentialMapper() throws Exception { + new AddLdapRealm.Builder(TEST_LDAP_REALM_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .identityMapping(new AddLdapRealm.IdentityMappingBuilder() + .rdnIdentifier("someId") + .otpCredentialMapper(new AddLdapRealm.OtpCredentialMapperBuilder() + .algorithmFrom("algFrom") + .hashFrom("hashFrom") + .seedFrom("seedFrom") + .sequenceFrom(null) + .build()) + .build()) + .build(); + fail("Creating command with null identity-mapping.otp-credential-mapper.sequence-from should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapRealm_emptySequenceFrom_otpCredentialMapper() throws Exception { + new AddLdapRealm.Builder(TEST_LDAP_REALM_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .identityMapping(new AddLdapRealm.IdentityMappingBuilder() + .rdnIdentifier("someId") + .otpCredentialMapper(new AddLdapRealm.OtpCredentialMapperBuilder() + .algorithmFrom("algFrom") + .hashFrom("hashFrom") + .seedFrom("seedFrom") + .sequenceFrom("") + .build()) + .build()) + .build(); + fail("Creating command with empty identity-mapping.otp-credential-mapper.sequence-from should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapRealm_nullValue_newIdentityAttributesBuilder() throws Exception { + new AddLdapRealm.Builder(TEST_LDAP_REALM_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .identityMapping(new AddLdapRealm.IdentityMappingBuilder() + .rdnIdentifier("someId") + .addNewIdentityAttributes(new AddLdapRealm.NewIdentityAttributesBuilder() + .addValues(null) + .build()) + .build()) + .build(); + fail("Creating command with null values of new-identity-attributes should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapRealm_noValue_newIdentityAttributesBuilder() throws Exception { + new AddLdapRealm.Builder(TEST_LDAP_REALM_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .identityMapping(new AddLdapRealm.IdentityMappingBuilder() + .rdnIdentifier("someId") + .addNewIdentityAttributes(new AddLdapRealm.NewIdentityAttributesBuilder() + .build()) + .build()) + .build(); + fail("Creating command with no values of new-identity-attributes should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapRealm_emptyValue_newIdentityAttributesBuilder() throws Exception { + new AddLdapRealm.Builder(TEST_LDAP_REALM_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .identityMapping(new AddLdapRealm.IdentityMappingBuilder() + .rdnIdentifier("someId") + .addNewIdentityAttributes(new AddLdapRealm.NewIdentityAttributesBuilder() + .addValues() + .build()) + .build()) + .build(); + fail("Creating command with empty values of new-identity-attributes should throw exception"); + } + + private void checkAttribute(String attribute, String expectedValue) throws IOException { + checkAttribute(TEST_LDAP_REALM_ADDRESS, attribute, expectedValue); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddPropertiesRealmOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddPropertiesRealmOnlineTest.java new file mode 100644 index 00000000..2fc3bcda --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddPropertiesRealmOnlineTest.java @@ -0,0 +1,195 @@ +package org.wildfly.extras.creaper.commands.elytron.realm; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.FileWriter; +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddPropertiesRealmOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_PROPERTIES_REALM_NAME = "CreaperTestPropertiesRealm"; + private static final Address TEST_PROPERTIES_REALM_ADDRESS = SUBSYSTEM_ADDRESS + .and("properties-realm", TEST_PROPERTIES_REALM_NAME); + private static final String TEST_PROPERTIES_REALM_NAME2 = "CreaperTestPropertiesRealm2"; + private static final Address TEST_PROPERTIES_REALM_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("properties-realm", TEST_PROPERTIES_REALM_NAME2); + + @ClassRule + public static TemporaryFolder tmp = new TemporaryFolder(); + + private static File usersProperties; + + @BeforeClass + public static void createUsersProperties() throws Exception { + usersProperties = tmp.newFile(); + FileWriter fw = null; + try { + fw = new FileWriter(usersProperties); + fw.write("#$REALM_NAME=" + TEST_PROPERTIES_REALM_NAME + "$"); + } finally { + if (fw != null) { + fw.close(); + } + } + } + + @AfterClass + public static void removeUsersProperties() throws Exception { + if (usersProperties != null) { + usersProperties.delete(); + } + } + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_PROPERTIES_REALM_ADDRESS); + ops.removeIfExists(TEST_PROPERTIES_REALM_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addSimplePropertiesRealm() throws Exception { + AddPropertiesRealm addPropertiesRealm = new AddPropertiesRealm.Builder(TEST_PROPERTIES_REALM_NAME) + .userProperiesPath(usersProperties.getAbsolutePath()) + .build(); + + client.apply(addPropertiesRealm); + + assertTrue("Properties realm should be created", ops.exists(TEST_PROPERTIES_REALM_ADDRESS)); + + } + + @Test + public void addTwoSimplePropertiesRealms() throws Exception { + AddPropertiesRealm addPropertiesRealm = new AddPropertiesRealm.Builder(TEST_PROPERTIES_REALM_NAME) + .userProperiesPath(usersProperties.getAbsolutePath()) + .build(); + + AddPropertiesRealm addPropertiesRealm2 = new AddPropertiesRealm.Builder(TEST_PROPERTIES_REALM_NAME2) + .userProperiesPath(usersProperties.getAbsolutePath()) + .build(); + + client.apply(addPropertiesRealm); + client.apply(addPropertiesRealm2); + + assertTrue("Properties realm should be created", ops.exists(TEST_PROPERTIES_REALM_ADDRESS)); + assertTrue("Second properties realm should be created", ops.exists(TEST_PROPERTIES_REALM_ADDRESS2)); + } + + @Test + public void addFullPropertiesRealm() throws Exception { + AddPropertiesRealm addPropertiesRealm = new AddPropertiesRealm.Builder(TEST_PROPERTIES_REALM_NAME) + .userProperiesPath("mgmt-users.properties") + .userPropertiesRelativeTo("jboss.server.config.dir") + .groupsProperiesPath("mgmt-groups.properties") + .groupsPropertiesRelativeTo("jboss.server.config.dir") + .plainText(true) + .digestRealmName("someDigestRealmName") + .groupsAttribute("myGroup") + .build(); + + client.apply(addPropertiesRealm); + + assertTrue("Properties realm should be created", ops.exists(TEST_PROPERTIES_REALM_ADDRESS)); + + checkAttribute(TEST_PROPERTIES_REALM_ADDRESS, "users-properties.path", "mgmt-users.properties"); + checkAttribute(TEST_PROPERTIES_REALM_ADDRESS, "users-properties.relative-to", "jboss.server.config.dir"); + checkAttribute(TEST_PROPERTIES_REALM_ADDRESS, "users-properties.plain-text", "true"); + checkAttribute(TEST_PROPERTIES_REALM_ADDRESS, "users-properties.digest-realm-name", "someDigestRealmName"); + checkAttribute(TEST_PROPERTIES_REALM_ADDRESS, "groups-properties.path", "mgmt-groups.properties"); + checkAttribute(TEST_PROPERTIES_REALM_ADDRESS, "groups-properties.relative-to", "jboss.server.config.dir"); + checkAttribute(TEST_PROPERTIES_REALM_ADDRESS, "groups-attribute", "myGroup"); + } + + @Test(expected = CommandFailedException.class) + public void addExistPropertiesRealmNotAllowed() throws Exception { + AddPropertiesRealm addPropertiesRealm = new AddPropertiesRealm.Builder(TEST_PROPERTIES_REALM_NAME) + .userProperiesPath(usersProperties.getAbsolutePath()) + .build(); + + AddPropertiesRealm addPropertiesRealm2 = new AddPropertiesRealm.Builder(TEST_PROPERTIES_REALM_NAME) + .userProperiesPath("mgmt-users.properties") + .userPropertiesRelativeTo("jboss.server.config.dir") + .build(); + + client.apply(addPropertiesRealm); + assertTrue("Properties realm should be created", ops.exists(TEST_PROPERTIES_REALM_ADDRESS)); + client.apply(addPropertiesRealm2); + fail("Properties realm CreaperTestPropertiesRealm already exists in configuration, exception should be thrown"); + + } + + @Test + public void addExistPropertiesRealmAllowed() throws Exception { + AddPropertiesRealm addPropertiesRealm = new AddPropertiesRealm.Builder(TEST_PROPERTIES_REALM_NAME) + .userProperiesPath(usersProperties.getAbsolutePath()) + .build(); + + AddPropertiesRealm addPropertiesRealm2 = new AddPropertiesRealm.Builder(TEST_PROPERTIES_REALM_NAME) + .userProperiesPath("mgmt-users.properties") + .userPropertiesRelativeTo("jboss.server.config.dir") + .replaceExisting() + .build(); + + client.apply(addPropertiesRealm); + assertTrue("Properties realm should be created", ops.exists(TEST_PROPERTIES_REALM_ADDRESS)); + client.apply(addPropertiesRealm2); + assertTrue("Properties realm should be created", ops.exists(TEST_PROPERTIES_REALM_ADDRESS)); + // check whether it was really rewritten + checkAttribute(TEST_PROPERTIES_REALM_ADDRESS, "users-properties.path", "mgmt-users.properties"); + } + + @Test(expected = IllegalArgumentException.class) + public void addPropertiesRealm_nullName() throws Exception { + new AddPropertiesRealm.Builder(null) + .userProperiesPath(usersProperties.getAbsolutePath()) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addPropertiesRealm_emptyName() throws Exception { + new AddPropertiesRealm.Builder("") + .userProperiesPath(usersProperties.getAbsolutePath()) + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addPropertiesRealm_nullUserProperiesPath() throws Exception { + new AddPropertiesRealm.Builder(TEST_PROPERTIES_REALM_NAME) + .userProperiesPath(null) + .build(); + fail("Creating command with null user properties path name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addPropertiesRealm_emptyUserProperiesPath() throws Exception { + new AddPropertiesRealm.Builder(TEST_PROPERTIES_REALM_NAME) + .userProperiesPath("") + .build(); + fail("Creating command with empty user properties path name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addPropertiesRealm_addGroupsPropertiesRelativeToWithoutGroupsProperiesPath() throws Exception { + new AddPropertiesRealm.Builder(TEST_PROPERTIES_REALM_NAME) + .groupsPropertiesRelativeTo("jboss.server.config.dir") + .build(); + fail("Creating command with defined groups properties relative-to and without groups properties path should throw exception"); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddTokenRealmOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddTokenRealmOnlineTest.java new file mode 100644 index 00000000..40371a88 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/realm/AddTokenRealmOnlineTest.java @@ -0,0 +1,363 @@ +package org.wildfly.extras.creaper.commands.elytron.realm; + +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import org.bouncycastle.util.encoders.Base64; +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.commands.elytron.tls.AddClientSSLContext; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +@RunWith(Arquillian.class) +public class AddTokenRealmOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_TOKEN_REALM_NAME = "CreaperTestTokenRealm"; + private static final Address TEST_TOKEN_REALM_ADDRESS = SUBSYSTEM_ADDRESS + .and("token-realm", TEST_TOKEN_REALM_NAME); + private static final String TEST_TOKEN_REALM_NAME2 = "CreaperTestTokenRealm2"; + private static final Address TEST_TOKEN_REALM_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("token-realm", TEST_TOKEN_REALM_NAME2); + + private static final String TEST_CLIENT_SSL_CONTEXT = "CreaperTestClientSSLContext"; + private static final Address TEST_CLIENT_SSL_CONTEXT_ADDRESS = SUBSYSTEM_ADDRESS.and("client-ssl-context", + TEST_CLIENT_SSL_CONTEXT); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_TOKEN_REALM_ADDRESS); + ops.removeIfExists(TEST_TOKEN_REALM_ADDRESS2); + ops.removeIfExists(TEST_CLIENT_SSL_CONTEXT_ADDRESS); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleTokenRealmWithJwt() throws Exception { + AddTokenRealm addTokenRealm = new AddTokenRealm.Builder(TEST_TOKEN_REALM_NAME) + .jwt(new AddTokenRealm.JwtBuilder().build()) + .build(); + + client.apply(addTokenRealm); + assertTrue("Token realm should be created", ops.exists(TEST_TOKEN_REALM_ADDRESS)); + } + + @Test + public void addSimpleTokenRealmWithOauth() throws Exception { + AddTokenRealm addTokenRealm = new AddTokenRealm.Builder(TEST_TOKEN_REALM_NAME) + .oauth2Introspection(new AddTokenRealm.Oauth2IntrospectionBuilder() + .clientId("someClient") + .clientSecret("someClientSecret") + .introspectionUrl("http://www.example.com") + .build()) + .build(); + + client.apply(addTokenRealm); + assertTrue("Token realm should be created", ops.exists(TEST_TOKEN_REALM_ADDRESS)); + } + + @Test + public void addTwoSimpleTokenRealmsWithJwt() throws Exception { + AddTokenRealm addTokenRealm = new AddTokenRealm.Builder(TEST_TOKEN_REALM_NAME) + .jwt(new AddTokenRealm.JwtBuilder() + .build()) + .build(); + + AddTokenRealm addTokenRealm2 = new AddTokenRealm.Builder(TEST_TOKEN_REALM_NAME2) + .jwt(new AddTokenRealm.JwtBuilder().build()) + .build(); + + client.apply(addTokenRealm); + client.apply(addTokenRealm2); + + assertTrue("Token realm should be created", ops.exists(TEST_TOKEN_REALM_ADDRESS)); + assertTrue("Second token realm should be created", ops.exists(TEST_TOKEN_REALM_ADDRESS2)); + } + + @Test + public void addTwoSimpleTokenRealmsWithOauth() throws Exception { + AddTokenRealm addTokenRealm = new AddTokenRealm.Builder(TEST_TOKEN_REALM_NAME) + .oauth2Introspection(new AddTokenRealm.Oauth2IntrospectionBuilder() + .clientId("someClient") + .clientSecret("someClientSecret") + .introspectionUrl("http://www.example.com") + .build()) + .build(); + + AddTokenRealm addTokenRealm2 = new AddTokenRealm.Builder(TEST_TOKEN_REALM_NAME2) + .oauth2Introspection(new AddTokenRealm.Oauth2IntrospectionBuilder() + .clientId("someClient") + .clientSecret("someClientSecret") + .introspectionUrl("http://www.example.com") + .build()) + .build(); + + client.apply(addTokenRealm); + client.apply(addTokenRealm2); + + assertTrue("Token realm should be created", ops.exists(TEST_TOKEN_REALM_ADDRESS)); + assertTrue("Second token realm should be created", ops.exists(TEST_TOKEN_REALM_ADDRESS2)); + } + + @Test + public void addTwoSimpleTokenRealmsCombined() throws Exception { + AddTokenRealm addTokenRealm = new AddTokenRealm.Builder(TEST_TOKEN_REALM_NAME) + .jwt(new AddTokenRealm.JwtBuilder().build()) + .build(); + + AddTokenRealm addTokenRealm2 = new AddTokenRealm.Builder(TEST_TOKEN_REALM_NAME2) + .oauth2Introspection(new AddTokenRealm.Oauth2IntrospectionBuilder() + .clientId("someClient") + .clientSecret("someClientSecret") + .introspectionUrl("http://www.example.com") + .build()) + .build(); + + client.apply(addTokenRealm); + client.apply(addTokenRealm2); + + assertTrue("Token realm should be created", ops.exists(TEST_TOKEN_REALM_ADDRESS)); + assertTrue("Second token realm should be created", ops.exists(TEST_TOKEN_REALM_ADDRESS2)); + } + + @Test + public void addFullTokenRealmWithJwt() throws Exception { + String pemPublicKey = getPublicKeyInPmeFormat(); + AddTokenRealm addTokenRealm = new AddTokenRealm.Builder(TEST_TOKEN_REALM_NAME) + .jwt(new AddTokenRealm.JwtBuilder() + .addIssuer("someIssuer") + .addAudience("someAudience") + .publicKey(pemPublicKey) + .build()) + .principalClaim("somePrincipalClaim") + .build(); + + client.apply(addTokenRealm); + assertTrue("Token realm should be created", ops.exists(TEST_TOKEN_REALM_ADDRESS)); + + checkAttribute(TEST_TOKEN_REALM_ADDRESS, "jwt.issuer[0]", "someIssuer"); + checkAttribute(TEST_TOKEN_REALM_ADDRESS, "jwt.audience[0]", "someAudience"); + checkAttribute(TEST_TOKEN_REALM_ADDRESS, "jwt.public-key", pemPublicKey); + checkAttribute(TEST_TOKEN_REALM_ADDRESS, "principal-claim", "somePrincipalClaim"); + } + + @Test + public void addFullTokenRealmWithOauth() throws Exception { + AddClientSSLContext addClientSSLContext = new AddClientSSLContext.Builder(TEST_CLIENT_SSL_CONTEXT) + .build(); + client.apply(addClientSSLContext); + assertTrue("SSL context should be created", ops.exists(TEST_CLIENT_SSL_CONTEXT_ADDRESS)); + + AddTokenRealm addTokenRealm = new AddTokenRealm.Builder(TEST_TOKEN_REALM_NAME) + .oauth2Introspection(new AddTokenRealm.Oauth2IntrospectionBuilder() + .clientId("someClient") + .clientSecret("someClientSecret") + .introspectionUrl("http://www.example.com") + .clientSslContext(TEST_CLIENT_SSL_CONTEXT) + .hostNameVerificationPolicy("ANY") + .build()) + .principalClaim("somePrincipalClaim") + .build(); + + client.apply(addTokenRealm); + assertTrue("Token realm should be created", ops.exists(TEST_TOKEN_REALM_ADDRESS)); + + checkAttribute(TEST_TOKEN_REALM_ADDRESS, "oauth2-introspection.client-id", "someClient"); + checkAttribute(TEST_TOKEN_REALM_ADDRESS, "oauth2-introspection.client-secret", "someClientSecret"); + checkAttribute(TEST_TOKEN_REALM_ADDRESS, "oauth2-introspection.introspection-url", "http://www.example.com"); + checkAttribute(TEST_TOKEN_REALM_ADDRESS, "oauth2-introspection.client-ssl-context", TEST_CLIENT_SSL_CONTEXT); + checkAttribute(TEST_TOKEN_REALM_ADDRESS, "oauth2-introspection.host-name-verification-policy", "ANY"); + checkAttribute(TEST_TOKEN_REALM_ADDRESS, "principal-claim", "somePrincipalClaim"); + } + + @Test(expected = CommandFailedException.class) + public void addExistTokenRealmNotAllowed() throws Exception { + AddTokenRealm addTokenRealm = new AddTokenRealm.Builder(TEST_TOKEN_REALM_NAME) + .jwt(new AddTokenRealm.JwtBuilder() + .addIssuer("someIssuer") + .addAudience("someAudience") + .build()) + .build(); + + AddTokenRealm addTokenRealm2 = new AddTokenRealm.Builder(TEST_TOKEN_REALM_NAME) + .jwt(new AddTokenRealm.JwtBuilder() + .addIssuer("someOtherIssuer") + .addAudience("someAudience") + .build()) + .build(); + + client.apply(addTokenRealm); + assertTrue("Token realm should be created", ops.exists(TEST_TOKEN_REALM_ADDRESS)); + client.apply(addTokenRealm2); + fail("Token realm CreaperTestTokenRealm already exists in configuration, exception should be thrown"); + } + + @Test(expected = CommandFailedException.class) + public void addExistTokenRealmAllowed() throws Exception { + AddTokenRealm addTokenRealm = new AddTokenRealm.Builder(TEST_TOKEN_REALM_NAME) + .jwt(new AddTokenRealm.JwtBuilder() + .addIssuer("someIssuer") + .addAudience("someAudience") + .build()) + .build(); + + AddTokenRealm addTokenRealm2 = new AddTokenRealm.Builder(TEST_TOKEN_REALM_NAME) + .jwt(new AddTokenRealm.JwtBuilder() + .addIssuer("someOtherIssuer") + .addAudience("someAudience") + .build()) + .build(); + + client.apply(addTokenRealm); + assertTrue("Token realm should be created", ops.exists(TEST_TOKEN_REALM_ADDRESS)); + client.apply(addTokenRealm2); + assertTrue("Token realm should be created", ops.exists(TEST_TOKEN_REALM_ADDRESS)); + // check whether it was really rewritten + checkAttribute(TEST_TOKEN_REALM_ADDRESS, "jwt.issuer[0]", "someOtherIssuer"); + } + + @Test(expected = IllegalArgumentException.class) + public void addTokenRealm_nullName() throws Exception { + new AddTokenRealm.Builder(null) + .jwt(new AddTokenRealm.JwtBuilder() + .addIssuer("someIssuer") + .addAudience("someAudience") + .build()) + .build(); + + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addTokenRealm_emptyName() throws Exception { + new AddTokenRealm.Builder("") + .jwt(new AddTokenRealm.JwtBuilder() + .addIssuer("someIssuer") + .addAudience("someAudience") + .build()) + .build(); + + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addTokenRealmWithJwt_nullIssuer() throws Exception { + new AddTokenRealm.Builder(TEST_TOKEN_REALM_NAME) + .jwt(new AddTokenRealm.JwtBuilder() + .addIssuer(null) + .addAudience("someAudience") + .build()) + .build(); + + fail("Creating command with null issuer should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addTokenRealmWithJwt_nullAudience() throws Exception { + new AddTokenRealm.Builder(TEST_TOKEN_REALM_NAME) + .jwt(new AddTokenRealm.JwtBuilder() + .addIssuer("someIssuer") + .addAudience(null) + .build()) + .build(); + + fail("Creating command with null audience should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addTokenRealmWithOauth_nullClientId() throws Exception { + new AddTokenRealm.Builder(TEST_TOKEN_REALM_NAME) + .oauth2Introspection(new AddTokenRealm.Oauth2IntrospectionBuilder() + .clientId(null) + .clientSecret("someClientSecret") + .introspectionUrl("http://www.example.com") + .build()) + .build(); + + fail("Creating command with null client-id should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addTokenRealmWithOauth_emptyClientId() throws Exception { + new AddTokenRealm.Builder(TEST_TOKEN_REALM_NAME) + .oauth2Introspection(new AddTokenRealm.Oauth2IntrospectionBuilder() + .clientId("") + .clientSecret("someClientSecret") + .introspectionUrl("http://www.example.com") + .build()) + .build(); + + fail("Creating command with empty client-id should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addTokenRealmWithOauth_nullClientSecret() throws Exception { + new AddTokenRealm.Builder(TEST_TOKEN_REALM_NAME) + .oauth2Introspection(new AddTokenRealm.Oauth2IntrospectionBuilder() + .clientId("someClient") + .clientSecret(null) + .introspectionUrl("http://www.example.com") + .build()) + .build(); + + fail("Creating command with null client-secret should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addTokenRealmWithOauth_emptyClientSecret() throws Exception { + new AddTokenRealm.Builder(TEST_TOKEN_REALM_NAME) + .oauth2Introspection(new AddTokenRealm.Oauth2IntrospectionBuilder() + .clientId("someClient") + .clientSecret("") + .introspectionUrl("http://www.example.com") + .build()) + .build(); + + fail("Creating command with empty client-secret should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addTokenRealmWithOauth_nullIntrospectionUrl() throws Exception { + new AddTokenRealm.Builder(TEST_TOKEN_REALM_NAME) + .oauth2Introspection(new AddTokenRealm.Oauth2IntrospectionBuilder() + .clientId("someClient") + .clientSecret("someClientSecret") + .introspectionUrl(null) + .build()) + .build(); + + fail("Creating command with null introspection-url should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addTokenRealmWithOauth_emptyIntrospectionUrl() throws Exception { + new AddTokenRealm.Builder(TEST_TOKEN_REALM_NAME) + .oauth2Introspection(new AddTokenRealm.Oauth2IntrospectionBuilder() + .clientId("someClient") + .clientSecret("someClientSecret") + .introspectionUrl("") + .build()) + .build(); + + fail("Creating command with empty introspection-url should throw exception"); + } + + private static String getPublicKeyInPmeFormat() throws NoSuchAlgorithmException { + KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); + KeyPair pair = keyGen.generateKeyPair(); + PublicKey pub = pair.getPublic(); + + String pemPublicKey = "-----BEGIN PUBLIC KEY-----\n"; + pemPublicKey += Base64.toBase64String(pub.getEncoded()); + pemPublicKey += "\n-----END PUBLIC KEY-----"; + + return pemPublicKey; + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddAggregateSaslServerFactoryOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddAggregateSaslServerFactoryOnlineTest.java new file mode 100644 index 00000000..db71da33 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddAggregateSaslServerFactoryOnlineTest.java @@ -0,0 +1,207 @@ +package org.wildfly.extras.creaper.commands.elytron.sasl; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddAggregateSaslServerFactoryOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_SERVER_FACTORY_NAME = "CreaperTestAggregateSaslServerFactory"; + private static final Address TEST_SERVER_FACTORY_ADDRESS = SUBSYSTEM_ADDRESS + .and("aggregate-sasl-server-factory", TEST_SERVER_FACTORY_NAME); + private static final String TEST_SERVER_FACTORY_NAME2 = "CreaperTestAggregateSaslServerFactory2"; + private static final Address TEST_SERVER_FACTORY_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("aggregate-sasl-server-factory", TEST_SERVER_FACTORY_NAME2); + + private static final String TEST_PROVIDER_SERVER_FACTORY_NAME = "CreaperTestProviderSaslServerFactory"; + private static final Address TEST_PROVIDER_SERVER_FACTORY_ADDRESS = SUBSYSTEM_ADDRESS + .and("provider-sasl-server-factory", TEST_PROVIDER_SERVER_FACTORY_NAME); + private final AddProviderSaslServerFactory addProviderSaslServerFactory + = new AddProviderSaslServerFactory.Builder(TEST_PROVIDER_SERVER_FACTORY_NAME) + .build(); + private static final String TEST_PROVIDER_SERVER_FACTORY_NAME2 = "CreaperTestProviderSaslServerFactory2"; + private static final Address TEST_PROVIDER_SERVER_FACTORY_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("provider-sasl-server-factory", TEST_PROVIDER_SERVER_FACTORY_NAME2); + private final AddProviderSaslServerFactory addProviderSaslServerFactory2 + = new AddProviderSaslServerFactory.Builder(TEST_PROVIDER_SERVER_FACTORY_NAME2) + .build(); + private static final String TEST_PROVIDER_SERVER_FACTORY_NAME3 = "CreaperTestProviderSaslServerFactory3"; + private static final Address TEST_PROVIDER_SERVER_FACTORY_ADDRESS3 = SUBSYSTEM_ADDRESS + .and("provider-sasl-server-factory", TEST_PROVIDER_SERVER_FACTORY_NAME3); + private final AddProviderSaslServerFactory addProviderSaslServerFactory3 + = new AddProviderSaslServerFactory.Builder(TEST_PROVIDER_SERVER_FACTORY_NAME3) + .build(); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_SERVER_FACTORY_ADDRESS); + ops.removeIfExists(TEST_SERVER_FACTORY_ADDRESS2); + ops.removeIfExists(TEST_PROVIDER_SERVER_FACTORY_ADDRESS); + ops.removeIfExists(TEST_PROVIDER_SERVER_FACTORY_ADDRESS2); + ops.removeIfExists(TEST_PROVIDER_SERVER_FACTORY_ADDRESS3); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleAggregateSaslServerFactory() throws Exception { + client.apply(addProviderSaslServerFactory); + client.apply(addProviderSaslServerFactory2); + + AddAggregateSaslServerFactory addAggregateSaslServerFactory + = new AddAggregateSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .addSaslServerFactories(TEST_PROVIDER_SERVER_FACTORY_NAME, + TEST_PROVIDER_SERVER_FACTORY_NAME2) + .build(); + + client.apply(addAggregateSaslServerFactory); + + assertTrue("Aggregate sasl server factory should be created", ops.exists(TEST_SERVER_FACTORY_ADDRESS)); + } + + @Test + public void addTwoAggregateSaslServerFactories() throws Exception { + client.apply(addProviderSaslServerFactory); + client.apply(addProviderSaslServerFactory2); + + AddAggregateSaslServerFactory addAggregateSaslServerFactory + = new AddAggregateSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .addSaslServerFactories(TEST_PROVIDER_SERVER_FACTORY_NAME, + TEST_PROVIDER_SERVER_FACTORY_NAME2) + .build(); + + AddAggregateSaslServerFactory addAggregateSaslServerFactory2 + = new AddAggregateSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME2) + .addSaslServerFactories(TEST_PROVIDER_SERVER_FACTORY_NAME, + TEST_PROVIDER_SERVER_FACTORY_NAME2) + .build(); + client.apply(addAggregateSaslServerFactory); + client.apply(addAggregateSaslServerFactory2); + + assertTrue("Aggregate sasl server factory should be created", ops.exists(TEST_SERVER_FACTORY_ADDRESS)); + assertTrue("Second aggregate sasl server factory should be created", ops.exists(TEST_SERVER_FACTORY_ADDRESS2)); + } + + @Test + public void addFullAggregateSaslServerFactory() throws Exception { + client.apply(addProviderSaslServerFactory); + client.apply(addProviderSaslServerFactory2); + client.apply(addProviderSaslServerFactory3); + + AddAggregateSaslServerFactory addAggregateSaslServerFactory + = new AddAggregateSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .addSaslServerFactories(TEST_PROVIDER_SERVER_FACTORY_NAME, + TEST_PROVIDER_SERVER_FACTORY_NAME2, + TEST_PROVIDER_SERVER_FACTORY_NAME3) + .build(); + + client.apply(addAggregateSaslServerFactory); + + assertTrue("Aggregate sasl server factory should be created", ops.exists(TEST_SERVER_FACTORY_ADDRESS)); + + checkAttribute(TEST_SERVER_FACTORY_ADDRESS, "sasl-server-factories[0]", TEST_PROVIDER_SERVER_FACTORY_NAME); + checkAttribute(TEST_SERVER_FACTORY_ADDRESS, "sasl-server-factories[1]", TEST_PROVIDER_SERVER_FACTORY_NAME2); + checkAttribute(TEST_SERVER_FACTORY_ADDRESS, "sasl-server-factories[2]", TEST_PROVIDER_SERVER_FACTORY_NAME3); + } + + @Test(expected = CommandFailedException.class) + public void addExistAggregateSaslServerFactoryNotAllowed() throws Exception { + client.apply(addProviderSaslServerFactory); + client.apply(addProviderSaslServerFactory2); + + AddAggregateSaslServerFactory addAggregateSaslServerFactory + = new AddAggregateSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .addSaslServerFactories(TEST_PROVIDER_SERVER_FACTORY_NAME, + TEST_PROVIDER_SERVER_FACTORY_NAME2) + .build(); + + AddAggregateSaslServerFactory addAggregateSaslServerFactory2 + = new AddAggregateSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .addSaslServerFactories(TEST_PROVIDER_SERVER_FACTORY_NAME, + TEST_PROVIDER_SERVER_FACTORY_NAME3) + .build(); + + client.apply(addAggregateSaslServerFactory); + assertTrue("Aggregate sasl server factory should be created", ops.exists(TEST_SERVER_FACTORY_ADDRESS)); + client.apply(addAggregateSaslServerFactory2); + fail("Aggregate sasl server factory CreaperTestAggregateSaslServerFactory already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistAggregateSaslServerFactoryAllowed() throws Exception { + client.apply(addProviderSaslServerFactory); + client.apply(addProviderSaslServerFactory2); + client.apply(addProviderSaslServerFactory3); + + AddAggregateSaslServerFactory addAggregateSaslServerFactory + = new AddAggregateSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .addSaslServerFactories(TEST_PROVIDER_SERVER_FACTORY_NAME, + TEST_PROVIDER_SERVER_FACTORY_NAME2) + .build(); + + AddAggregateSaslServerFactory addAggregateSaslServerFactory2 + = new AddAggregateSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .addSaslServerFactories(TEST_PROVIDER_SERVER_FACTORY_NAME, + TEST_PROVIDER_SERVER_FACTORY_NAME3) + .replaceExisting() + .build(); + + client.apply(addAggregateSaslServerFactory); + assertTrue("Aggregate sasl server factory should be created", ops.exists(TEST_SERVER_FACTORY_ADDRESS)); + client.apply(addAggregateSaslServerFactory2); + assertTrue("Aggregate sasl server factory should be created", ops.exists(TEST_SERVER_FACTORY_ADDRESS)); + // check whether it was really rewritten + checkAttribute(TEST_SERVER_FACTORY_ADDRESS, "sasl-server-factories[1]", + TEST_PROVIDER_SERVER_FACTORY_NAME3); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregateSaslServerFactory_nullName() throws Exception { + new AddAggregateSaslServerFactory.Builder(null) + .addSaslServerFactories(TEST_PROVIDER_SERVER_FACTORY_NAME, + TEST_PROVIDER_SERVER_FACTORY_NAME2) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregateSaslServerFactory_emptyName() throws Exception { + new AddAggregateSaslServerFactory.Builder("") + .addSaslServerFactories(TEST_PROVIDER_SERVER_FACTORY_NAME, + TEST_PROVIDER_SERVER_FACTORY_NAME2) + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregateSaslServerFactory_nullSaslServerFactories() throws Exception { + new AddAggregateSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .addSaslServerFactories(null) + .build(); + fail("Creating command with null sasl-server-factories should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregateSaslServerFactory_emptySaslServerFactories() throws Exception { + new AddAggregateSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .addSaslServerFactories("") + .build(); + fail("Creating command with empty sasl-server-factories should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAggregateSaslServerFactory_oneSaslServerFactories() throws Exception { + new AddAggregateSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .addSaslServerFactories(TEST_PROVIDER_SERVER_FACTORY_NAME) + .build(); + fail("Creating command with only one sasl-server-factories should throw exception"); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddConfigurableSaslServerFactoryOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddConfigurableSaslServerFactoryOnlineTest.java new file mode 100644 index 00000000..9b07be52 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddConfigurableSaslServerFactoryOnlineTest.java @@ -0,0 +1,255 @@ +package org.wildfly.extras.creaper.commands.elytron.sasl; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.commands.elytron.Property; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddConfigurableSaslServerFactoryOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_SERVER_FACTORY_NAME = "CreaperTestConfigurableSaslServerFactory"; + private static final Address TEST_SERVER_FACTORY_ADDRESS = SUBSYSTEM_ADDRESS + .and("configurable-sasl-server-factory", TEST_SERVER_FACTORY_NAME); + private static final String TEST_SERVER_FACTORY_NAME2 = "CreaperTestConfigurableSaslServerFactory2"; + private static final Address TEST_SERVER_FACTORY_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("configurable-sasl-server-factory", TEST_SERVER_FACTORY_NAME2); + + private static final String TEST_PROVIDER_SERVER_FACTORY_NAME = "CreaperTestProviderSaslServerFactory"; + private static final Address TEST_PROVIDER_SERVER_FACTORY_ADDRESS = SUBSYSTEM_ADDRESS + .and("provider-sasl-server-factory", TEST_PROVIDER_SERVER_FACTORY_NAME); + private final AddProviderSaslServerFactory addProviderSaslServerFactory + = new AddProviderSaslServerFactory.Builder(TEST_PROVIDER_SERVER_FACTORY_NAME) + .build(); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_SERVER_FACTORY_ADDRESS); + ops.removeIfExists(TEST_SERVER_FACTORY_ADDRESS2); + ops.removeIfExists(TEST_PROVIDER_SERVER_FACTORY_ADDRESS); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleConfigurableSaslServerFactory() throws Exception { + client.apply(addProviderSaslServerFactory); + + AddConfigurableSaslServerFactory addConfigurableSaslServerFactory + = new AddConfigurableSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .saslServerFactory(TEST_PROVIDER_SERVER_FACTORY_NAME) + .build(); + + client.apply(addConfigurableSaslServerFactory); + + assertTrue("Configurable sasl server factory should be created", ops.exists(TEST_SERVER_FACTORY_ADDRESS)); + } + + @Test + public void addTwoConfigurableSaslServerFactories() throws Exception { + client.apply(addProviderSaslServerFactory); + + AddConfigurableSaslServerFactory addConfigurableSaslServerFactory + = new AddConfigurableSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .saslServerFactory(TEST_PROVIDER_SERVER_FACTORY_NAME) + .build(); + + AddConfigurableSaslServerFactory addConfigurableSaslServerFactory2 + = new AddConfigurableSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME2) + .saslServerFactory(TEST_PROVIDER_SERVER_FACTORY_NAME) + .build(); + + client.apply(addConfigurableSaslServerFactory); + client.apply(addConfigurableSaslServerFactory2); + + assertTrue("Configurable sasl server factory should be created", ops.exists(TEST_SERVER_FACTORY_ADDRESS)); + assertTrue("Second configurable sasl server factory should be created", + ops.exists(TEST_SERVER_FACTORY_ADDRESS2)); + } + + @Test + public void addFullConfigurableSaslServerFactory() throws Exception { + client.apply(addProviderSaslServerFactory); + + AddConfigurableSaslServerFactory addConfigurableSaslServerFactory + = new AddConfigurableSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .saslServerFactory(TEST_PROVIDER_SERVER_FACTORY_NAME) + .protocol("someProtocol") + .serverName("someServerName") + .addFilters(new AddConfigurableSaslServerFactory.FilterBuilder() + .predefinedFilter("BINDING") + .enabling(false) + .build(), + new AddConfigurableSaslServerFactory.FilterBuilder() + .patternFilter("somePattern") + .build()) + .addProperties(new Property("a", "b"), + new Property("c", "d")) + .build(); + + client.apply(addConfigurableSaslServerFactory); + + assertTrue("Configurable sasl server factory should be created", ops.exists(TEST_SERVER_FACTORY_ADDRESS)); + + checkAttribute(TEST_SERVER_FACTORY_ADDRESS, "sasl-server-factory", TEST_PROVIDER_SERVER_FACTORY_NAME); + checkAttribute(TEST_SERVER_FACTORY_ADDRESS, "protocol", "someProtocol"); + checkAttribute(TEST_SERVER_FACTORY_ADDRESS, "server-name", "someServerName"); + checkAttribute(TEST_SERVER_FACTORY_ADDRESS, "filters[0].predefined-filter", "BINDING"); + checkAttribute(TEST_SERVER_FACTORY_ADDRESS, "filters[0].enabling", "false"); + checkAttribute(TEST_SERVER_FACTORY_ADDRESS, "filters[1].pattern-filter", "somePattern"); + checkAttribute(TEST_SERVER_FACTORY_ADDRESS, "properties.a", "b"); + checkAttribute(TEST_SERVER_FACTORY_ADDRESS, "properties.c", "d"); + } + + @Test(expected = CommandFailedException.class) + public void addExistConfigurableSaslServerFactoryNotAllowed() throws Exception { + client.apply(addProviderSaslServerFactory); + + AddConfigurableSaslServerFactory addConfigurableSaslServerFactory + = new AddConfigurableSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .saslServerFactory(TEST_PROVIDER_SERVER_FACTORY_NAME) + .addProperties(new Property("a", "b")) + .build(); + + AddConfigurableSaslServerFactory addConfigurableSaslServerFactory2 + = new AddConfigurableSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .saslServerFactory(TEST_PROVIDER_SERVER_FACTORY_NAME) + .addProperties(new Property("c", "d")) + .build(); + + client.apply(addConfigurableSaslServerFactory); + assertTrue("Configurable sasl server factory should be created", ops.exists(TEST_SERVER_FACTORY_ADDRESS)); + client.apply(addConfigurableSaslServerFactory2); + fail("Configurable sasl server factory CreaperTestConfigurableSaslServerFactory already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistConfigurableSaslServerFactoryAllowed() throws Exception { + client.apply(addProviderSaslServerFactory); + + AddConfigurableSaslServerFactory addConfigurableSaslServerFactory + = new AddConfigurableSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .saslServerFactory(TEST_PROVIDER_SERVER_FACTORY_NAME) + .addProperties(new Property("a", "b")) + .build(); + + AddConfigurableSaslServerFactory addConfigurableSaslServerFactory2 + = new AddConfigurableSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .saslServerFactory(TEST_PROVIDER_SERVER_FACTORY_NAME) + .addProperties(new Property("c", "d")) + .replaceExisting() + .build(); + + client.apply(addConfigurableSaslServerFactory); + assertTrue("Configurable sasl server factory should be created", ops.exists(TEST_SERVER_FACTORY_ADDRESS)); + client.apply(addConfigurableSaslServerFactory2); + assertTrue("Configurable sasl server factory should be created", ops.exists(TEST_SERVER_FACTORY_ADDRESS)); + // check whether it was really rewritten + checkAttribute(TEST_SERVER_FACTORY_ADDRESS, "properties.c", "d"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConfigurableSaslServerFactory_nullName() throws Exception { + new AddConfigurableSaslServerFactory.Builder(null) + .saslServerFactory(TEST_PROVIDER_SERVER_FACTORY_NAME) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConfigurableSaslServerFactory_emptyName() throws Exception { + new AddConfigurableSaslServerFactory.Builder("") + .saslServerFactory(TEST_PROVIDER_SERVER_FACTORY_NAME) + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConfigurableSaslServerFactory_nullSaslServerFactory() throws Exception { + new AddConfigurableSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .saslServerFactory(null) + .build(); + fail("Creating command with null sasl-server-factory should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConfigurableSaslServerFactory_emptySaslServerFactory() throws Exception { + new AddConfigurableSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .saslServerFactory("") + .build(); + fail("Creating command with empty sasl-server-factory should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConfigurableSaslServerFactory_nullPatternFilter() throws Exception { + new AddConfigurableSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .saslServerFactory(TEST_PROVIDER_SERVER_FACTORY_NAME) + .addFilters(new AddConfigurableSaslServerFactory.FilterBuilder().patternFilter(null).build()) + .build(); + fail("Creating command with null pattern-filter and without any predefined-filter in filters should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConfigurableSaslServerFactory_emptyPatternFilter() throws Exception { + new AddConfigurableSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .saslServerFactory(TEST_PROVIDER_SERVER_FACTORY_NAME) + .addFilters(new AddConfigurableSaslServerFactory.FilterBuilder().patternFilter("").build()) + .build(); + fail("Creating command with empty pattern-filter and without any predefined-filter in filters should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConfigurableSaslServerFactory_nullPredefinedFilter() throws Exception { + new AddConfigurableSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .saslServerFactory(TEST_PROVIDER_SERVER_FACTORY_NAME) + .addFilters(new AddConfigurableSaslServerFactory.FilterBuilder().predefinedFilter(null).build()) + .build(); + fail("Creating command with null predefined-filter and without any pattern-filter in filters should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConfigurableSaslServerFactory_emptyPredefinedFilter() throws Exception { + new AddConfigurableSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .saslServerFactory(TEST_PROVIDER_SERVER_FACTORY_NAME) + .addFilters(new AddConfigurableSaslServerFactory.FilterBuilder().predefinedFilter("").build()) + .build(); + fail("Creating command with empty predefined-filter and without any pattern-filter in filters should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConfigurableSaslServerFactory_nullFilters() throws Exception { + new AddConfigurableSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .saslServerFactory(TEST_PROVIDER_SERVER_FACTORY_NAME) + .addFilters(null) + .build(); + fail("Creating command with null filters should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConfigurableSaslServerFactory_nullProperties() throws Exception { + new AddConfigurableSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .saslServerFactory(TEST_PROVIDER_SERVER_FACTORY_NAME) + .addProperties(null) + .build(); + fail("Creating command with null properties should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addConfigurableSaslServerFactory_bothPredefinedFilterAndPatternFilter() throws Exception { + new AddConfigurableSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .saslServerFactory(TEST_PROVIDER_SERVER_FACTORY_NAME) + .addFilters(new AddConfigurableSaslServerFactory.FilterBuilder() + .patternFilter("somePattern") + .predefinedFilter("BINDING") + .build()) + .build(); + fail("Creating command both predefined-filter a pattern-filter should throw exception"); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddMechanismProviderFilteringSaslServerFactoryOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddMechanismProviderFilteringSaslServerFactoryOnlineTest.java new file mode 100644 index 00000000..9e60a80e --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddMechanismProviderFilteringSaslServerFactoryOnlineTest.java @@ -0,0 +1,246 @@ +package org.wildfly.extras.creaper.commands.elytron.sasl; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddMechanismProviderFilteringSaslServerFactoryOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_FACTORY_NAME = "CreaperTestFactory"; + private static final Address TEST_FACTORY_ADDRESS = SUBSYSTEM_ADDRESS + .and("mechanism-provider-filtering-sasl-server-factory", TEST_FACTORY_NAME); + private static final String TEST_FACTORY_NAME2 = "CreaperTestFactory2"; + private static final Address TEST_FACTORY_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("mechanism-provider-filtering-sasl-server-factory", TEST_FACTORY_NAME2); + + private static final String TEST_SERVER_FACTORY_NAME + = "CreaperTestProviderSaslServerFactory"; + private static final Address TEST_SERVER_FACTORY_ADDRESS = SUBSYSTEM_ADDRESS + .and("provider-sasl-server-factory", TEST_SERVER_FACTORY_NAME); + private final AddProviderSaslServerFactory addProviderSaslServerFactory + = new AddProviderSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .build(); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_FACTORY_ADDRESS); + ops.removeIfExists(TEST_FACTORY_ADDRESS2); + ops.removeIfExists(TEST_SERVER_FACTORY_ADDRESS); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleMechanismProviderFilteringSaslServerFactory() throws Exception { + client.apply(addProviderSaslServerFactory); + + AddMechanismProviderFilteringSaslServerFactory addMechanismProviderFilteringSaslServerFactory + = new AddMechanismProviderFilteringSaslServerFactory.Builder(TEST_FACTORY_NAME) + .saslServerFactory(TEST_SERVER_FACTORY_NAME) + .build(); + + client.apply(addMechanismProviderFilteringSaslServerFactory); + + assertTrue("Mechanism provider filtering sasl server factory should be created", + ops.exists(TEST_FACTORY_ADDRESS)); + } + + @Test + public void addTwoMechanismProviderFilteringSaslServerFactories() throws Exception { + client.apply(addProviderSaslServerFactory); + + AddMechanismProviderFilteringSaslServerFactory addMechanismProviderFilteringSaslServerFactory + = new AddMechanismProviderFilteringSaslServerFactory.Builder(TEST_FACTORY_NAME) + .saslServerFactory(TEST_SERVER_FACTORY_NAME) + .build(); + AddMechanismProviderFilteringSaslServerFactory addMechanismProviderFilteringSaslServerFactory2 + = new AddMechanismProviderFilteringSaslServerFactory.Builder(TEST_FACTORY_NAME2) + .saslServerFactory(TEST_SERVER_FACTORY_NAME) + .build(); + + client.apply(addMechanismProviderFilteringSaslServerFactory); + client.apply(addMechanismProviderFilteringSaslServerFactory2); + + assertTrue("Mechanism provider filtering sasl server factory should be created", + ops.exists(TEST_FACTORY_ADDRESS)); + assertTrue("Second mechanism provider filtering sasl server factory should be created", + ops.exists(TEST_FACTORY_ADDRESS2)); + } + + @Test + public void addFullMechanismProviderFilteringSaslServerFactory() throws Exception { + client.apply(addProviderSaslServerFactory); + + AddMechanismProviderFilteringSaslServerFactory addMechanismProviderFilteringSaslServerFactory + = new AddMechanismProviderFilteringSaslServerFactory.Builder(TEST_FACTORY_NAME) + .saslServerFactory(TEST_SERVER_FACTORY_NAME) + .enabling(false) + .addFilters(new AddMechanismProviderFilteringSaslServerFactory.FilterBuilder() + .providerName("someProviderName") + .mechanismName("someMechanismName") + .providerVersion(2.0) + .versionComparison( + AddMechanismProviderFilteringSaslServerFactory.VersionComparison.GREATER_THAN) + .build(), + new AddMechanismProviderFilteringSaslServerFactory.FilterBuilder() + .providerName("someProviderName2") + .mechanismName("someMechanismName2") + .providerVersion(1.5) + .versionComparison(AddMechanismProviderFilteringSaslServerFactory.VersionComparison.LESS_THAN) + .build()) + .build(); + + client.apply(addMechanismProviderFilteringSaslServerFactory); + + assertTrue("Mechanism provider filtering sasl server factory should be created", + ops.exists(TEST_FACTORY_ADDRESS)); + + checkAttribute("sasl-server-factory", TEST_SERVER_FACTORY_NAME); + checkAttribute("enabling", "false"); + + checkAttribute("filters[0].provider-name", "someProviderName"); + checkAttribute("filters[0].mechanism-name", "someMechanismName"); + checkAttribute("filters[0].provider-version", "2.0"); + checkAttribute("filters[0].version-comparison", "greater-than"); + + checkAttribute("filters[1].provider-name", "someProviderName2"); + checkAttribute("filters[1].mechanism-name", "someMechanismName2"); + checkAttribute("filters[1].provider-version", "1.5"); + checkAttribute("filters[1].version-comparison", "less-than"); + } + + @Test(expected = CommandFailedException.class) + public void addExistMechanismProviderFilteringSaslServerFactoryNotAllowed() throws Exception { + client.apply(addProviderSaslServerFactory); + + AddMechanismProviderFilteringSaslServerFactory addMechanismProviderFilteringSaslServerFactory + = new AddMechanismProviderFilteringSaslServerFactory.Builder(TEST_FACTORY_NAME) + .saslServerFactory(TEST_SERVER_FACTORY_NAME) + .addFilters(new AddMechanismProviderFilteringSaslServerFactory.FilterBuilder() + .providerName("someProviderName") + .build()) + .build(); + AddMechanismProviderFilteringSaslServerFactory addMechanismProviderFilteringSaslServerFactory2 + = new AddMechanismProviderFilteringSaslServerFactory.Builder(TEST_FACTORY_NAME) + .saslServerFactory(TEST_SERVER_FACTORY_NAME) + .addFilters(new AddMechanismProviderFilteringSaslServerFactory.FilterBuilder() + .providerName("someProviderName2") + .build()) + .build(); + + client.apply(addMechanismProviderFilteringSaslServerFactory); + assertTrue("Mechanism provider filtering sasl server factory should be created", + ops.exists(TEST_FACTORY_ADDRESS)); + client.apply(addMechanismProviderFilteringSaslServerFactory2); + fail("Mechanism provider filtering sasl server factory CreaperTestFactory already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistMechanismProviderFilteringSaslServerFactoryAllowed() throws Exception { + client.apply(addProviderSaslServerFactory); + + AddMechanismProviderFilteringSaslServerFactory addMechanismProviderFilteringSaslServerFactory + = new AddMechanismProviderFilteringSaslServerFactory.Builder(TEST_FACTORY_NAME) + .saslServerFactory(TEST_SERVER_FACTORY_NAME) + .addFilters(new AddMechanismProviderFilteringSaslServerFactory.FilterBuilder() + .providerName("someProviderName") + .build()) + .build(); + AddMechanismProviderFilteringSaslServerFactory addMechanismProviderFilteringSaslServerFactory2 + = new AddMechanismProviderFilteringSaslServerFactory.Builder(TEST_FACTORY_NAME) + .saslServerFactory(TEST_SERVER_FACTORY_NAME) + .addFilters(new AddMechanismProviderFilteringSaslServerFactory.FilterBuilder() + .providerName("someProviderName2") + .build()) + .replaceExisting() + .build(); + + client.apply(addMechanismProviderFilteringSaslServerFactory); + assertTrue("Mechanism provider filtering sasl server factory should be created", + ops.exists(TEST_FACTORY_ADDRESS)); + client.apply(addMechanismProviderFilteringSaslServerFactory2); + assertTrue("Mechanism provider filtering sasl server factory should be created", + ops.exists(TEST_FACTORY_ADDRESS)); + // check whether it was really rewritten + checkAttribute("filters[0].provider-name", "someProviderName2"); + } + + @Test(expected = IllegalArgumentException.class) + public void addMechanismProviderFilteringSaslServerFactory_nullName() throws Exception { + new AddMechanismProviderFilteringSaslServerFactory.Builder(null) + .saslServerFactory(TEST_SERVER_FACTORY_NAME) + .addFilters(new AddMechanismProviderFilteringSaslServerFactory.FilterBuilder() + .providerName("someProviderName") + .build()) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addMechanismProviderFilteringSaslServerFactory_emptyName() throws Exception { + new AddMechanismProviderFilteringSaslServerFactory.Builder("") + .saslServerFactory(TEST_SERVER_FACTORY_NAME) + .addFilters(new AddMechanismProviderFilteringSaslServerFactory.FilterBuilder() + .providerName("someProviderName") + .build()) + .build(); + fail("Creating command with empty name should throw exception"); + + } + + @Test(expected = IllegalArgumentException.class) + public void addMechanismProviderFilteringSaslServerFactory_nullSaslServerFactory() throws Exception { + new AddMechanismProviderFilteringSaslServerFactory.Builder(TEST_FACTORY_NAME) + .saslServerFactory(null) + .addFilters(new AddMechanismProviderFilteringSaslServerFactory.FilterBuilder() + .providerName("someProviderName") + .build()) + .build(); + fail("Creating command with null sasl-server-factory should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addMechanismProviderFilteringSaslServerFactory_emptySaslServerFactory() throws Exception { + new AddMechanismProviderFilteringSaslServerFactory.Builder(TEST_FACTORY_NAME) + .saslServerFactory("") + .addFilters(new AddMechanismProviderFilteringSaslServerFactory.FilterBuilder() + .providerName("someProviderName") + .build()) + .build(); + fail("Creating command with empty sasl-server-factory should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addMechanismProviderFilteringSaslServerFactory_nullProviderName_filters() throws Exception { + new AddMechanismProviderFilteringSaslServerFactory.Builder(TEST_FACTORY_NAME) + .saslServerFactory(TEST_SERVER_FACTORY_NAME) + .addFilters(new AddMechanismProviderFilteringSaslServerFactory.FilterBuilder() + .providerName(null) + .build()) + .build(); + fail("Creating command with null provider name in filters should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addMechanismProviderFilteringSaslServerFactory_emptyProviderName_filters() throws Exception { + new AddMechanismProviderFilteringSaslServerFactory.Builder(TEST_FACTORY_NAME) + .saslServerFactory(TEST_SERVER_FACTORY_NAME) + .addFilters(new AddMechanismProviderFilteringSaslServerFactory.FilterBuilder() + .providerName("") + .build()) + .build(); + fail("Creating command with empty provider name in filters should throw exception"); + } + + private void checkAttribute(String attribute, String expectedValue) throws IOException { + checkAttribute(TEST_FACTORY_ADDRESS, attribute, expectedValue); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddProviderSaslServerFactoryOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddProviderSaslServerFactoryOnlineTest.java new file mode 100644 index 00000000..4b6fc6b4 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddProviderSaslServerFactoryOnlineTest.java @@ -0,0 +1,130 @@ +package org.wildfly.extras.creaper.commands.elytron.sasl; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddProviderSaslServerFactoryOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_SERVER_FACTORY_NAME = "CreaperTestProviderSaslServerFactory"; + private static final Address TEST_SERVER_FACTORY_ADDRESS = SUBSYSTEM_ADDRESS + .and("provider-sasl-server-factory", TEST_SERVER_FACTORY_NAME); + private static final String TEST_SERVER_FACTORY_NAME2 = "CreaperTestProviderSaslServerFactory2"; + private static final Address TEST_SERVER_FACTORY_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("provider-sasl-server-factory", TEST_SERVER_FACTORY_NAME2); + + private static final String PROVIDER_LOADER_NAME = "elytron"; + private static final String PROVIDER_LOADER_NAME2 = "combined-providers"; + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_SERVER_FACTORY_ADDRESS); + ops.removeIfExists(TEST_SERVER_FACTORY_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleProviderSaslServerFactory() throws Exception { + AddProviderSaslServerFactory addProviderSaslServerFactory + = new AddProviderSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .build(); + + client.apply(addProviderSaslServerFactory); + + assertTrue("Provider sasl server factory should be created", ops.exists(TEST_SERVER_FACTORY_ADDRESS)); + } + + @Test + public void addTwoProviderSaslServerFactories() throws Exception { + AddProviderSaslServerFactory addProviderSaslServerFactory + = new AddProviderSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .build(); + + AddProviderSaslServerFactory addProviderSaslServerFactory2 + = new AddProviderSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME2) + .build(); + + client.apply(addProviderSaslServerFactory); + client.apply(addProviderSaslServerFactory2); + + assertTrue("Provider sasl server factory should be created", ops.exists(TEST_SERVER_FACTORY_ADDRESS)); + assertTrue("Second provider sasl server factory should be created", ops.exists(TEST_SERVER_FACTORY_ADDRESS2)); + } + + @Test + public void addFullProviderSaslServerFactory() throws Exception { + AddProviderSaslServerFactory addProviderSaslServerFactory + = new AddProviderSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .providers(PROVIDER_LOADER_NAME) + .build(); + + client.apply(addProviderSaslServerFactory); + + assertTrue("Provider sasl server factory should be created", ops.exists(TEST_SERVER_FACTORY_ADDRESS)); + + checkAttribute(TEST_SERVER_FACTORY_ADDRESS, "providers", PROVIDER_LOADER_NAME); + + } + + @Test(expected = CommandFailedException.class) + public void addExistProviderSaslServerFactoryNotAllowed() throws Exception { + AddProviderSaslServerFactory addProviderSaslServerFactory + = new AddProviderSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .providers(PROVIDER_LOADER_NAME) + .build(); + + AddProviderSaslServerFactory addProviderSaslServerFactory2 + = new AddProviderSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .providers(PROVIDER_LOADER_NAME2) + .build(); + + client.apply(addProviderSaslServerFactory); + assertTrue("Provider sasl server factory should be created", ops.exists(TEST_SERVER_FACTORY_ADDRESS)); + client.apply(addProviderSaslServerFactory2); + fail("Provider sasl server factory CreaperTestProviderSaslServerFactory already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistProviderSaslServerFactoryAllowed() throws Exception { + AddProviderSaslServerFactory addProviderSaslServerFactory + = new AddProviderSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .providers(PROVIDER_LOADER_NAME) + .build(); + + AddProviderSaslServerFactory addProviderSaslServerFactory2 + = new AddProviderSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .providers(PROVIDER_LOADER_NAME2) + .replaceExisting() + .build(); + + client.apply(addProviderSaslServerFactory); + assertTrue("Provider sasl server factory should be created", ops.exists(TEST_SERVER_FACTORY_ADDRESS)); + client.apply(addProviderSaslServerFactory2); + assertTrue("Provider sasl server factory should be created", ops.exists(TEST_SERVER_FACTORY_ADDRESS)); + // check whether it was really rewritten + checkAttribute(TEST_SERVER_FACTORY_ADDRESS, "providers", PROVIDER_LOADER_NAME2); + } + + @Test(expected = IllegalArgumentException.class) + public void addProviderSaslServerFactory_nullName() throws Exception { + new AddProviderSaslServerFactory.Builder(null) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addProviderSaslServerFactory_emptyName() throws Exception { + new AddProviderSaslServerFactory.Builder("") + .build(); + fail("Creating command with empty name should throw exception"); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddSaslAuthenticationFactoryOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddSaslAuthenticationFactoryOnlineTest.java new file mode 100644 index 00000000..852a47ae --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddSaslAuthenticationFactoryOnlineTest.java @@ -0,0 +1,475 @@ +package org.wildfly.extras.creaper.commands.elytron.sasl; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.commands.elytron.Mechanism; +import org.wildfly.extras.creaper.commands.elytron.credfactory.AddKerberosSecurityFactory; +import org.wildfly.extras.creaper.commands.elytron.domain.AddSecurityDomain; +import org.wildfly.extras.creaper.commands.elytron.mapper.AddConstantPrincipalTransformer; +import org.wildfly.extras.creaper.commands.elytron.mapper.AddSimpleRegexRealmMapper; +import org.wildfly.extras.creaper.commands.elytron.realm.AddFilesystemRealm; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddSaslAuthenticationFactoryOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_AUTHENTICATION_FACTORY_NAME + = "CreaperTestSaslAuthenticationFactory"; + private static final Address TEST_AUTHENTICATION_FACTORY_ADDRESS = SUBSYSTEM_ADDRESS + .and("sasl-authentication-factory", TEST_AUTHENTICATION_FACTORY_NAME); + private static final String TEST_AUTHENTICATION_FACTORY_NAME2 + = "CreaperTestSaslAuthenticationFactory2"; + private static final Address TEST_AUTHENTICATION_FACTORY_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("sasl-authentication-factory", TEST_AUTHENTICATION_FACTORY_NAME2); + + private static final String TEST_FILESYSTEM_REALM_NAME = "CreaperTestFilesystemRealm"; + private static final Address TEST_FILESYSTEM_REALM_ADDRESS = SUBSYSTEM_ADDRESS + .and("filesystem-realm", TEST_FILESYSTEM_REALM_NAME); + private final AddFilesystemRealm addFilesystemRealm = new AddFilesystemRealm.Builder(TEST_FILESYSTEM_REALM_NAME) + .path("/path/to/filesystem") + .build(); + + private static final String TEST_FILESYSTEM_REALM_NAME2 = "CreaperTestFilesystemRealm2"; + private static final Address TEST_FILESYSTEM_REALM_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("filesystem-realm", TEST_FILESYSTEM_REALM_NAME2); + private final AddFilesystemRealm addFilesystemRealm2 = new AddFilesystemRealm.Builder(TEST_FILESYSTEM_REALM_NAME2) + .path("/path/to/filesystem") + .build(); + + private static final String TEST_SECURITY_DOMAIN_NAME = "CreaperTestSecurityDomain"; + private static final Address TEST_SECURITY_DOMAIN_ADDRESS = SUBSYSTEM_ADDRESS + .and("security-domain", TEST_SECURITY_DOMAIN_NAME); + private final AddSecurityDomain addSecurityDomain = new AddSecurityDomain.Builder(TEST_SECURITY_DOMAIN_NAME) + .defaultRealm(TEST_FILESYSTEM_REALM_NAME) + .realms(new AddSecurityDomain.RealmBuilder(TEST_FILESYSTEM_REALM_NAME) + .build()) + .build(); + + private static final String TEST_SERVER_FACTORY_NAME + = "CreaperTestProviderSaslServerFactory"; + private static final Address TEST_SERVER_FACTORY_ADDRESS = SUBSYSTEM_ADDRESS + .and("provider-sasl-server-factory", TEST_SERVER_FACTORY_NAME); + private final AddProviderSaslServerFactory addProviderSaslServerFactory + = new AddProviderSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .build(); + + private static final String TEST_SERVER_FACTORY_NAME2 + = "CreaperTestProviderSaslServerFactory2"; + private static final Address TEST_SERVER_FACTORY_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("provider-sasl-server-factory", TEST_SERVER_FACTORY_NAME2); + private final AddProviderSaslServerFactory addProviderSaslServerFactory2 + = new AddProviderSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME2) + .build(); + + private static final String TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME = "CreaperTestConstantPrincipalTransformer"; + private static final Address TEST_CONSTANT_PRINCIPAL_TRANSFORMER_ADDRESS = SUBSYSTEM_ADDRESS + .and("constant-principal-transformer", TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME); + private final AddConstantPrincipalTransformer addConstantPrincipalTransformer + = new AddConstantPrincipalTransformer.Builder(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME) + .constant("name1") + .build(); + + private static final String TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2 = "CreaperTestConstantPrincipalTransformer2"; + private static final Address TEST_CONSTANT_PRINCIPAL_TRANSFORMER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("constant-principal-transformer", TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2); + private final AddConstantPrincipalTransformer addConstantPrincipalTransformer2 + = new AddConstantPrincipalTransformer.Builder(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .constant("name2") + .build(); + + private static final String TEST_SIMPLE_REGEX_REALM_MAPPER_NAME = "CreaperTestSimpleRegexRealmMapper"; + private static final Address TEST_SIMPLE_REGEX_REALM_MAPPER_ADDRESS = SUBSYSTEM_ADDRESS + .and("simple-regex-realm-mapper", TEST_SIMPLE_REGEX_REALM_MAPPER_NAME); + private final AddSimpleRegexRealmMapper addSimpleRegexRealmMapper + = new AddSimpleRegexRealmMapper.Builder(TEST_SIMPLE_REGEX_REALM_MAPPER_NAME) + .pattern("(somePattern)") + .build(); + + private static final String TEST_SIMPLE_REGEX_REALM_MAPPER_NAME2 = "CreaperTestSimpleRegexRealmMapper2"; + private static final Address TEST_SIMPLE_REGEX_REALM_MAPPER_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("simple-regex-realm-mapper", TEST_SIMPLE_REGEX_REALM_MAPPER_NAME2); + private final AddSimpleRegexRealmMapper addSimpleRegexRealmMapper2 + = new AddSimpleRegexRealmMapper.Builder(TEST_SIMPLE_REGEX_REALM_MAPPER_NAME2) + .pattern("(somePattern2)") + .build(); + + private static final String TEST_KERBEROS_SECURITY_FACTORY_NAME = "CreaperTestKerberosSecurityFactory"; + private static final Address TEST_KERBEROS_SECURITY_FACTORY_ADDRESS = SUBSYSTEM_ADDRESS + .and("kerberos-security-factory", TEST_KERBEROS_SECURITY_FACTORY_NAME); + private final AddKerberosSecurityFactory addKerberosSecurityFactory + = new AddKerberosSecurityFactory.Builder(TEST_KERBEROS_SECURITY_FACTORY_NAME) + .principal("principal1") + .path("/path/to/keytab") + .mechanismOIDs("1.2.840.113554.1.2.2") + .build(); + + private static final String TEST_KERBEROS_SECURITY_FACTORY_NAME2 = "CreaperTestKerberosSecurityFactory2"; + private static final Address TEST_KERBEROS_SECURITY_FACTORY_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("kerberos-security-factory", TEST_KERBEROS_SECURITY_FACTORY_NAME2); + private final AddKerberosSecurityFactory addKerberosSecurityFactory2 + = new AddKerberosSecurityFactory.Builder(TEST_KERBEROS_SECURITY_FACTORY_NAME2) + .principal("principal2") + .path("/path/to/keytab") + .mechanismOIDs("1.2.840.113554.1.2.2") + .build(); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_AUTHENTICATION_FACTORY_ADDRESS); + ops.removeIfExists(TEST_AUTHENTICATION_FACTORY_ADDRESS2); + ops.removeIfExists(TEST_SECURITY_DOMAIN_ADDRESS); + ops.removeIfExists(TEST_FILESYSTEM_REALM_ADDRESS); + ops.removeIfExists(TEST_FILESYSTEM_REALM_ADDRESS2); + ops.removeIfExists(TEST_SERVER_FACTORY_ADDRESS); + ops.removeIfExists(TEST_SERVER_FACTORY_ADDRESS2); + ops.removeIfExists(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_ADDRESS); + ops.removeIfExists(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_ADDRESS2); + ops.removeIfExists(TEST_SIMPLE_REGEX_REALM_MAPPER_ADDRESS); + ops.removeIfExists(TEST_SIMPLE_REGEX_REALM_MAPPER_ADDRESS2); + ops.removeIfExists(TEST_KERBEROS_SECURITY_FACTORY_ADDRESS); + ops.removeIfExists(TEST_KERBEROS_SECURITY_FACTORY_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleSaslAuthenticationFactory() throws Exception { + client.apply(addFilesystemRealm); + client.apply(addSecurityDomain); + client.apply(addProviderSaslServerFactory); + + AddSaslAuthenticationFactory addSaslAuthenticationFactory + = new AddSaslAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .saslServerFactory(TEST_SERVER_FACTORY_NAME) + .build(); + + client.apply(addSaslAuthenticationFactory); + + assertTrue("Sasl authentication factory should be created", ops.exists(TEST_AUTHENTICATION_FACTORY_ADDRESS)); + } + + @Test + public void addTwoSaslAuthenticationFactories() throws Exception { + client.apply(addFilesystemRealm); + client.apply(addSecurityDomain); + client.apply(addProviderSaslServerFactory); + + AddSaslAuthenticationFactory addSaslAuthenticationFactory + = new AddSaslAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .saslServerFactory(TEST_SERVER_FACTORY_NAME) + .build(); + + AddSaslAuthenticationFactory addSaslAuthenticationFactory2 + = new AddSaslAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME2) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .saslServerFactory(TEST_SERVER_FACTORY_NAME) + .build(); + + client.apply(addSaslAuthenticationFactory); + client.apply(addSaslAuthenticationFactory2); + + assertTrue("Sasl authentication factory should be created", ops.exists(TEST_AUTHENTICATION_FACTORY_ADDRESS)); + assertTrue("Second sasl authentication factory should be created", + ops.exists(TEST_AUTHENTICATION_FACTORY_ADDRESS2)); + } + + @Test + public void addFullSaslAuthenticationFactory() throws Exception { + client.apply(addFilesystemRealm); + client.apply(addFilesystemRealm2); + client.apply(addSecurityDomain); + client.apply(addProviderSaslServerFactory); + client.apply(addConstantPrincipalTransformer); + client.apply(addConstantPrincipalTransformer2); + client.apply(addSimpleRegexRealmMapper); + client.apply(addSimpleRegexRealmMapper2); + client.apply(addKerberosSecurityFactory); + client.apply(addKerberosSecurityFactory2); + + AddSaslAuthenticationFactory addSaslAuthenticationFactory + = new AddSaslAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .saslServerFactory(TEST_SERVER_FACTORY_NAME) + .addMechanismConfigurations(new Mechanism.Builder() + .credentialSecurityFactory(TEST_KERBEROS_SECURITY_FACTORY_NAME) + .mechanismName("someName") + .hostName("someHostName") + .protocol("someProtocol") + .preRealmPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME) + .postRealmPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .finalPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME) + .realmMapper(TEST_SIMPLE_REGEX_REALM_MAPPER_NAME) + .addMechanismRealmConfigurations(new Mechanism.MechanismRealmBuilder() + .realmName(TEST_FILESYSTEM_REALM_NAME) + .preRealmPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME) + .postRealmPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .finalPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME) + .realmMapper(TEST_SIMPLE_REGEX_REALM_MAPPER_NAME) + .build(), + new Mechanism.MechanismRealmBuilder() + .realmName(TEST_FILESYSTEM_REALM_NAME2) + .preRealmPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .postRealmPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME) + .finalPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .realmMapper(TEST_SIMPLE_REGEX_REALM_MAPPER_NAME2) + .build()) + .build(), + new Mechanism.Builder() + .credentialSecurityFactory(TEST_KERBEROS_SECURITY_FACTORY_NAME2) + .mechanismName("someName2") + .hostName("someHostName2") + .protocol("someProtocol2") + .preRealmPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .postRealmPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME) + .finalPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .realmMapper(TEST_SIMPLE_REGEX_REALM_MAPPER_NAME2) + .addMechanismRealmConfigurations(new Mechanism.MechanismRealmBuilder() + .realmName(TEST_FILESYSTEM_REALM_NAME2) + .preRealmPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .postRealmPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .finalPrincipalTransformer(TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2) + .realmMapper(TEST_SIMPLE_REGEX_REALM_MAPPER_NAME2) + .build()) + .build()) + .build(); + + client.apply(addSaslAuthenticationFactory); + + assertTrue("Sasl authentication factory should be created", ops.exists(TEST_AUTHENTICATION_FACTORY_ADDRESS)); + + checkAttribute("security-domain", TEST_SECURITY_DOMAIN_NAME); + checkAttribute("sasl-server-factory", TEST_SERVER_FACTORY_NAME); + + checkAttribute("mechanism-configurations[0].mechanism-name", "someName"); + checkAttribute("mechanism-configurations[0].host-name", "someHostName"); + checkAttribute("mechanism-configurations[0].protocol", "someProtocol"); + checkAttribute("mechanism-configurations[0].pre-realm-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME); + checkAttribute("mechanism-configurations[0].post-realm-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2); + checkAttribute("mechanism-configurations[0].final-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME); + checkAttribute("mechanism-configurations[0].realm-mapper", TEST_SIMPLE_REGEX_REALM_MAPPER_NAME); + checkAttribute("mechanism-configurations[0].credential-security-factory", TEST_KERBEROS_SECURITY_FACTORY_NAME); + + checkAttribute("mechanism-configurations[0].mechanism-realm-configurations[0].realm-name", + TEST_FILESYSTEM_REALM_NAME); + checkAttribute("mechanism-configurations[0].mechanism-realm-configurations[0].pre-realm-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME); + checkAttribute("mechanism-configurations[0].mechanism-realm-configurations[0].post-realm-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2); + checkAttribute("mechanism-configurations[0].mechanism-realm-configurations[0].final-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME); + checkAttribute("mechanism-configurations[0].mechanism-realm-configurations[0].realm-mapper", + TEST_SIMPLE_REGEX_REALM_MAPPER_NAME); + + checkAttribute("mechanism-configurations[0].mechanism-realm-configurations[1].realm-name", + TEST_FILESYSTEM_REALM_NAME2); + checkAttribute("mechanism-configurations[0].mechanism-realm-configurations[1].pre-realm-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2); + checkAttribute("mechanism-configurations[0].mechanism-realm-configurations[1].post-realm-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME); + checkAttribute("mechanism-configurations[0].mechanism-realm-configurations[1].final-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2); + checkAttribute("mechanism-configurations[0].mechanism-realm-configurations[1].realm-mapper", + TEST_SIMPLE_REGEX_REALM_MAPPER_NAME2); + + checkAttribute("mechanism-configurations[1].mechanism-name", "someName2"); + checkAttribute("mechanism-configurations[1].host-name", "someHostName2"); + checkAttribute("mechanism-configurations[1].protocol", "someProtocol2"); + checkAttribute("mechanism-configurations[1].pre-realm-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2); + checkAttribute("mechanism-configurations[1].post-realm-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME); + checkAttribute("mechanism-configurations[1].final-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2 + ); + checkAttribute("mechanism-configurations[1].realm-mapper", TEST_SIMPLE_REGEX_REALM_MAPPER_NAME2); + checkAttribute("mechanism-configurations[1].credential-security-factory", + TEST_KERBEROS_SECURITY_FACTORY_NAME2); + + checkAttribute("mechanism-configurations[1].mechanism-realm-configurations[0].realm-name", + TEST_FILESYSTEM_REALM_NAME2); + checkAttribute("mechanism-configurations[1].mechanism-realm-configurations[0].pre-realm-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2); + checkAttribute("mechanism-configurations[1].mechanism-realm-configurations[0].post-realm-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2); + checkAttribute("mechanism-configurations[1].mechanism-realm-configurations[0].final-principal-transformer", + TEST_CONSTANT_PRINCIPAL_TRANSFORMER_NAME2); + checkAttribute("mechanism-configurations[1].mechanism-realm-configurations[0].realm-mapper", + TEST_SIMPLE_REGEX_REALM_MAPPER_NAME2); + + } + + @Test(expected = CommandFailedException.class) + public void addExistSaslAuthenticationFactoryNotAllowed() throws Exception { + client.apply(addFilesystemRealm); + client.apply(addSecurityDomain); + client.apply(addProviderSaslServerFactory); + client.apply(addProviderSaslServerFactory2); + + AddSaslAuthenticationFactory addSaslAuthenticationFactory + = new AddSaslAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .saslServerFactory(TEST_SERVER_FACTORY_NAME) + .build(); + + AddSaslAuthenticationFactory addSaslAuthenticationFactory2 + = new AddSaslAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .saslServerFactory(TEST_SERVER_FACTORY_NAME2) + .build(); + + client.apply(addSaslAuthenticationFactory); + assertTrue("Sasl authentication factory should be created", ops.exists(TEST_AUTHENTICATION_FACTORY_ADDRESS)); + client.apply(addSaslAuthenticationFactory2); + fail("Sasl authentication factory CreaperTestSaslAuthenticationFactory already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistSaslAuthenticationFactoryAllowed() throws Exception { + client.apply(addFilesystemRealm); + client.apply(addSecurityDomain); + client.apply(addProviderSaslServerFactory); + client.apply(addProviderSaslServerFactory2); + + AddSaslAuthenticationFactory addSaslAuthenticationFactory + = new AddSaslAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .saslServerFactory(TEST_SERVER_FACTORY_NAME) + .build(); + + AddSaslAuthenticationFactory addSaslAuthenticationFactory2 + = new AddSaslAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .saslServerFactory(TEST_SERVER_FACTORY_NAME2) + .replaceExisting() + .build(); + + client.apply(addSaslAuthenticationFactory); + assertTrue("Sasl authentication factory should be created", ops.exists(TEST_AUTHENTICATION_FACTORY_ADDRESS)); + client.apply(addSaslAuthenticationFactory2); + assertTrue("Sasl authentication factory should be created", ops.exists(TEST_AUTHENTICATION_FACTORY_ADDRESS)); + // check whether it was really rewritten + checkAttribute("sasl-server-factory", TEST_SERVER_FACTORY_NAME2); + } + + @Test(expected = IllegalArgumentException.class) + public void addSaslAuthenticationFactory_nullName() throws Exception { + new AddSaslAuthenticationFactory.Builder(null) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .saslServerFactory(TEST_SERVER_FACTORY_NAME) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSaslAuthenticationFactory_emptyName() throws Exception { + new AddSaslAuthenticationFactory.Builder("") + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .saslServerFactory(TEST_SERVER_FACTORY_NAME) + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSaslAuthenticationFactory_nullSecurityDomain() throws Exception { + new AddSaslAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain(null) + .saslServerFactory(TEST_SERVER_FACTORY_NAME) + .build(); + fail("Creating command with null security domain should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSaslAuthenticationFactory_emptySecurityDomain() throws Exception { + new AddSaslAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain("") + .saslServerFactory(TEST_SERVER_FACTORY_NAME) + .build(); + fail("Creating command with empty security domain should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSaslAuthenticationFactory_nullSaslServerFactory() throws Exception { + new AddSaslAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .saslServerFactory(null) + .build(); + fail("Creating command with null sasl server factory should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSaslAuthenticationFactory_emptySaslServerFactory() throws Exception { + new AddSaslAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .saslServerFactory("") + .build(); + fail("Creating command with empty sasl server factory should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSaslAuthenticationFactory_nullConfigurations() throws Exception { + new AddSaslAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .saslServerFactory(TEST_SERVER_FACTORY_NAME) + .addMechanismConfigurations(null) + .build(); + fail("Creating command with null configuration should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSaslAuthenticationFactory_nullRealmConfigurations() throws Exception { + new AddSaslAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .saslServerFactory(TEST_SERVER_FACTORY_NAME) + .addMechanismConfigurations(new Mechanism.Builder() + .addMechanismRealmConfigurations(null) + .build()) + .build(); + fail("Creating command with null realm configuration should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSaslAuthenticationFactory_nullRealmName_mechanismRealm() throws Exception { + new AddSaslAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .saslServerFactory(TEST_SERVER_FACTORY_NAME) + .addMechanismConfigurations(new Mechanism.Builder() + .addMechanismRealmConfigurations(new Mechanism.MechanismRealmBuilder() + .realmName(null) + .build()) + .build()) + .build(); + fail("Creating command with null realm name in realm should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSaslAuthenticationFactory_emptyRealmName_mechanismRealm() throws Exception { + new AddSaslAuthenticationFactory.Builder(TEST_AUTHENTICATION_FACTORY_NAME) + .securityDomain(TEST_SECURITY_DOMAIN_NAME) + .saslServerFactory(TEST_SERVER_FACTORY_NAME) + .addMechanismConfigurations(new Mechanism.Builder() + .addMechanismRealmConfigurations(new Mechanism.MechanismRealmBuilder() + .realmName("") + .build()) + .build()) + .build(); + fail("Creating command with empty realm name in realm should throw exception"); + } + + private void checkAttribute(String attribute, String expectedValue) throws IOException { + checkAttribute(TEST_AUTHENTICATION_FACTORY_ADDRESS, attribute, expectedValue); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddServiceLoaderSaslServerFactoryOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddServiceLoaderSaslServerFactoryOnlineTest.java new file mode 100644 index 00000000..65960b8e --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/sasl/AddServiceLoaderSaslServerFactoryOnlineTest.java @@ -0,0 +1,132 @@ +package org.wildfly.extras.creaper.commands.elytron.sasl; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddServiceLoaderSaslServerFactoryOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_SERVER_FACTORY_NAME = "CreaperTestServiceLoaderSaslServerFactory"; + private static final Address TEST_SERVER_FACTORY_ADDRESS = SUBSYSTEM_ADDRESS + .and("service-loader-sasl-server-factory", TEST_SERVER_FACTORY_NAME); + private static final String TEST_SERVER_FACTORY_NAME2 = "CreaperTestServiceLoaderSaslServerFactory2"; + private static final Address TEST_SERVER_FACTORY_ADDRESS2 = SUBSYSTEM_ADDRESS + .and("service-loader-sasl-server-factory", TEST_SERVER_FACTORY_NAME2); + + private static final String ELYTRON_MODULE = "org.wildfly.security.elytron"; + private static final String ELYTRON_SUBSYTEM_MODULE = "org.wildfly.extension.elytron"; + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_SERVER_FACTORY_ADDRESS); + ops.removeIfExists(TEST_SERVER_FACTORY_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleServiceLoaderSaslServerFactory() throws Exception { + AddServiceLoaderSaslServerFactory addServiceLoaderSaslServerFactory + = new AddServiceLoaderSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .build(); + + client.apply(addServiceLoaderSaslServerFactory); + + assertTrue("Service loader sasl server factory should be created", ops.exists(TEST_SERVER_FACTORY_ADDRESS)); + + } + + @Test + public void addTwoServiceLoaderSaslServerFactories() throws Exception { + AddServiceLoaderSaslServerFactory addServiceLoaderSaslServerFactory + = new AddServiceLoaderSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .build(); + + AddServiceLoaderSaslServerFactory addServiceLoaderSaslServerFactory2 + = new AddServiceLoaderSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME2) + .build(); + + client.apply(addServiceLoaderSaslServerFactory); + client.apply(addServiceLoaderSaslServerFactory2); + + assertTrue("Service loader sasl server factory should be created", ops.exists(TEST_SERVER_FACTORY_ADDRESS)); + assertTrue("Second service loader sasl server factory should be created", + ops.exists(TEST_SERVER_FACTORY_ADDRESS2)); + } + + @Test + public void addFullServiceLoaderSaslServerFactory() throws Exception { + AddServiceLoaderSaslServerFactory addServiceLoaderSaslServerFactory + = new AddServiceLoaderSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .module(ELYTRON_MODULE) + .build(); + + client.apply(addServiceLoaderSaslServerFactory); + + assertTrue("Service loader sasl server factory should be created", ops.exists(TEST_SERVER_FACTORY_ADDRESS)); + + checkAttribute(TEST_SERVER_FACTORY_ADDRESS, "module", ELYTRON_MODULE); + + } + + @Test(expected = CommandFailedException.class) + public void addExistServiceLoaderSaslServerFactoryNotAllowed() throws Exception { + AddServiceLoaderSaslServerFactory addServiceLoaderSaslServerFactory + = new AddServiceLoaderSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .module(ELYTRON_MODULE) + .build(); + + AddServiceLoaderSaslServerFactory addServiceLoaderSaslServerFactory2 + = new AddServiceLoaderSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .module(ELYTRON_SUBSYTEM_MODULE) + .build(); + + client.apply(addServiceLoaderSaslServerFactory); + assertTrue("Service loader sasl server factory should be created", ops.exists(TEST_SERVER_FACTORY_ADDRESS)); + client.apply(addServiceLoaderSaslServerFactory2); + fail("Service loader sasl server factory CreaperTestServiceLoaderSaslServerFactory already exists in configuration, exception should be thrown"); + } + + @Test + public void addExistServiceLoaderSaslServerFactoryAllowed() throws Exception { + AddServiceLoaderSaslServerFactory addServiceLoaderSaslServerFactory + = new AddServiceLoaderSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .module(ELYTRON_MODULE) + .build(); + + AddServiceLoaderSaslServerFactory addServiceLoaderSaslServerFactory2 + = new AddServiceLoaderSaslServerFactory.Builder(TEST_SERVER_FACTORY_NAME) + .module(ELYTRON_SUBSYTEM_MODULE) + .replaceExisting() + .build(); + + client.apply(addServiceLoaderSaslServerFactory); + assertTrue("Service loader sasl server factory should be created", ops.exists(TEST_SERVER_FACTORY_ADDRESS)); + client.apply(addServiceLoaderSaslServerFactory2); + assertTrue("Service loader sasl server factory should be created", ops.exists(TEST_SERVER_FACTORY_ADDRESS)); + // check whether it was really rewritten + checkAttribute(TEST_SERVER_FACTORY_ADDRESS, "module", ELYTRON_SUBSYTEM_MODULE); + } + + @Test(expected = IllegalArgumentException.class) + public void addServiceLoaderSaslServerFactory_nullName() throws Exception { + new AddServiceLoaderSaslServerFactory.Builder(null) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addServiceLoaderSaslServerFactory_emptyName() throws Exception { + new AddServiceLoaderSaslServerFactory.Builder("") + .build(); + fail("Creating command with empty name should throw exception"); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/securityproperty/AddSecurityPropertyOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/securityproperty/AddSecurityPropertyOnlineTest.java new file mode 100644 index 00000000..0fdee4b5 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/securityproperty/AddSecurityPropertyOnlineTest.java @@ -0,0 +1,103 @@ +package org.wildfly.extras.creaper.commands.elytron.securityproperty; + +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; + +@RunWith(Arquillian.class) +public class AddSecurityPropertyOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_SECURITY_PROPERTY_NAME = "CreaperTestSecurityProperty"; + private static final String TEST_SECURITY_PROPERTY_FULL_NAME = "security-properties." + + TEST_SECURITY_PROPERTY_NAME; + private static final String TEST_SECURITY_PROPERTY_NAME2 = "CreaperTestSecurityProperty2"; + private static final String TEST_SECURITY_PROPERTY_FULL_NAME2 = "security-properties." + + TEST_SECURITY_PROPERTY_NAME2; + + @After + public void cleanup() throws Exception { + ops.undefineAttribute(SUBSYSTEM_ADDRESS, TEST_SECURITY_PROPERTY_FULL_NAME); + ops.undefineAttribute(SUBSYSTEM_ADDRESS, TEST_SECURITY_PROPERTY_FULL_NAME2); + } + + @Test + public void addSecurityProperty() throws Exception { + AddSecurityProperty addSecurityProperty = new AddSecurityProperty.Builder(TEST_SECURITY_PROPERTY_NAME) + .value("someSecretValue") + .build(); + client.apply(addSecurityProperty); + + checkAttribute(SUBSYSTEM_ADDRESS, TEST_SECURITY_PROPERTY_FULL_NAME, "someSecretValue"); + } + + @Test + public void addSecurityProperties() throws Exception { + AddSecurityProperty addSecurityProperty = new AddSecurityProperty.Builder(TEST_SECURITY_PROPERTY_NAME) + .value("someSecretValue") + .build(); + + AddSecurityProperty addSecurityProperty2 = new AddSecurityProperty.Builder(TEST_SECURITY_PROPERTY_NAME2) + .value("someSecretValue2") + .build(); + + client.apply(addSecurityProperty); + client.apply(addSecurityProperty2); + + checkAttribute(SUBSYSTEM_ADDRESS, TEST_SECURITY_PROPERTY_FULL_NAME, "someSecretValue"); + checkAttribute(SUBSYSTEM_ADDRESS, TEST_SECURITY_PROPERTY_FULL_NAME2, "someSecretValue2"); + } + + @Test + public void addSecurityPropertyAllowed() throws Exception { + AddSecurityProperty addSecurityProperty = new AddSecurityProperty.Builder(TEST_SECURITY_PROPERTY_NAME) + .value("someSecretValue") + .build(); + + AddSecurityProperty addSecurityProperty2 = new AddSecurityProperty.Builder(TEST_SECURITY_PROPERTY_NAME) + .value("differentSecretValue") + .build(); + + client.apply(addSecurityProperty); + checkAttribute(SUBSYSTEM_ADDRESS, TEST_SECURITY_PROPERTY_FULL_NAME, "someSecretValue"); + client.apply(addSecurityProperty2); + // check whether it was really rewritten + checkAttribute(SUBSYSTEM_ADDRESS, TEST_SECURITY_PROPERTY_FULL_NAME, "differentSecretValue"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSecurityProperty_nullKey() throws Exception { + new AddSecurityProperty.Builder(null) + .value("someSecretValue") + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSecurityProperty_emptyKey() throws Exception { + new AddSecurityProperty.Builder("") + .value("someSecretValue") + .build(); + fail("Creating command with empty name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSecurityProperty_nullValue() throws Exception { + new AddSecurityProperty.Builder(TEST_SECURITY_PROPERTY_NAME) + .value(null) + .build(); + fail("Creating command with null value should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addSecurityProperty_emptyValue() throws Exception { + new AddSecurityProperty.Builder(TEST_SECURITY_PROPERTY_NAME) + .value("") + .build(); + fail("Creating command with empty value should throw exception"); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AbstractAddSSLContextOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AbstractAddSSLContextOnlineTest.java new file mode 100644 index 00000000..21cf65ef --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AbstractAddSSLContextOnlineTest.java @@ -0,0 +1,115 @@ +package org.wildfly.extras.creaper.commands.elytron.tls; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.TrustManagerFactory; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.commands.elytron.CredentialRef; +import org.wildfly.extras.creaper.core.online.OnlineManagementClient; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +public abstract class AbstractAddSSLContextOnlineTest extends AbstractElytronOnlineTest { + + protected static final String TEST_KEY_STORE_NAME = "CreaperTestKeyStore"; + private static final String TEST_KEY_STORE_NAME2 = "CreaperTestKeyStore2"; + private static final Address TEST_KEY_STORE_ADDRESS = SUBSYSTEM_ADDRESS.and("key-store", TEST_KEY_STORE_NAME); + private static final Address TEST_KEY_STORE_ADDRESS2 = SUBSYSTEM_ADDRESS.and("key-store", TEST_KEY_STORE_NAME2); + private static final String TEST_KEY_STORE_TYPE = "JKS"; + private static final String TEST_KEY_STORE_PASSWORD = "password"; + private static final String TEST_KEY_PASSWORD = "password"; + + protected static final String TEST_KEY_MNGR_NAME = "CreaperTestKeyManager"; + private static final String TEST_KEY_MNGR_NAME2 = "CreaperTestKeyManager2"; + private static final Address TEST_KEY_MNGR_ADDRESS = SUBSYSTEM_ADDRESS.and("key-manager", TEST_KEY_MNGR_NAME); + private static final Address TEST_KEY_MNGR_ADDRESS2 = SUBSYSTEM_ADDRESS.and("key-manager", TEST_KEY_MNGR_NAME2); + private static final String TEST_KEY_MANAGER_ALGORITHM = KeyManagerFactory.getDefaultAlgorithm(); + + protected static final String TRUST_MNGR_NAME = "CreaperTestTrustManager"; + private static final String TRUST_MNGR_NAME2 = "CreaperTestTrustManager2"; + private static final Address TRUST_MNGR_ADDRESS = SUBSYSTEM_ADDRESS.and("trust-manager", TRUST_MNGR_NAME); + private static final Address TRUST_MNGR_ADDRESS2 = SUBSYSTEM_ADDRESS.and("trust-manager", TRUST_MNGR_NAME2); + private static final String TRUST_MANAGER_ALGORITHM = TrustManagerFactory.getDefaultAlgorithm(); + + + @BeforeClass + public static void addDependentResources() throws Exception { + OnlineManagementClient client = null; + try { + client = createManagementClient(); + AddKeyStore addKeyStore = new AddKeyStore.Builder(TEST_KEY_STORE_NAME) + .type(TEST_KEY_STORE_TYPE) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_STORE_PASSWORD) + .build()) + .build(); + AddKeyStore addKeyStore2 = new AddKeyStore.Builder(TEST_KEY_STORE_NAME2) + .type(TEST_KEY_STORE_TYPE) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_STORE_PASSWORD) + .build()) + .build(); + + AddKeyManager addKeyManager = new AddKeyManager.Builder(TEST_KEY_MNGR_NAME) + .algorithm(TEST_KEY_MANAGER_ALGORITHM) + .keyStore(TEST_KEY_STORE_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_PASSWORD) + .build()) + .build(); + AddKeyManager addKeyManager2 = new AddKeyManager.Builder(TEST_KEY_MNGR_NAME2) + .algorithm(TEST_KEY_MANAGER_ALGORITHM) + .keyStore(TEST_KEY_STORE_NAME2) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_PASSWORD) + .build()) + .build(); + + AddTrustManager addTrustManager = new AddTrustManager.Builder(TRUST_MNGR_NAME) + .algorithm(TRUST_MANAGER_ALGORITHM) + .keyStore(TEST_KEY_STORE_NAME) + .build(); + AddTrustManager addTrustManager2 = new AddTrustManager.Builder(TRUST_MNGR_NAME2) + .algorithm(TRUST_MANAGER_ALGORITHM) + .keyStore(TEST_KEY_STORE_NAME2) + .build(); + + client.apply(addKeyStore); + client.apply(addKeyStore2); + client.apply(addKeyManager); + client.apply(addKeyManager2); + client.apply(addTrustManager); + client.apply(addTrustManager2); + + } finally { + if (client != null) { + client.close(); + } + } + } + + @AfterClass + public static void removeDependentResources() throws Exception { + OnlineManagementClient client = null; + try { + client = createManagementClient(); + Operations ops = new Operations(client); + Administration administration = new Administration(client); + ops.removeIfExists(TRUST_MNGR_ADDRESS); + ops.removeIfExists(TRUST_MNGR_ADDRESS2); + ops.removeIfExists(TEST_KEY_MNGR_ADDRESS); + ops.removeIfExists(TEST_KEY_MNGR_ADDRESS2); + ops.removeIfExists(TEST_KEY_STORE_ADDRESS); + ops.removeIfExists(TEST_KEY_STORE_ADDRESS2); + administration.reloadIfRequired(); + } finally { + if (client != null) { + client.close(); + } + } + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddClientSSLContextOfflineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddClientSSLContextOfflineTest.java new file mode 100644 index 00000000..86a2125e --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddClientSSLContextOfflineTest.java @@ -0,0 +1,250 @@ +package org.wildfly.extras.creaper.commands.elytron.tls; + +import static org.junit.Assert.fail; +import static org.wildfly.extras.creaper.XmlAssert.assertXmlIdentical; + +import java.io.File; + +import org.custommonkey.xmlunit.XMLUnit; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.ManagementClient; +import org.wildfly.extras.creaper.core.offline.OfflineManagementClient; +import org.wildfly.extras.creaper.core.offline.OfflineOptions; + +import com.google.common.base.Charsets; +import com.google.common.io.Files; + +public class AddClientSSLContextOfflineTest { + + private static final String SUBSYSTEM_EMPTY = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_TLS_EMPTY = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_CLIENT_SSL_CONTEXTS_EMPTY = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_SIMPLE = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_EXPECTED_REPLACE = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_SECOND_CLIENT_SSL_CONTEXT = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_FULL = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + @Rule + public final TemporaryFolder tmp = new TemporaryFolder(); + + @Before + public void setUp() { + XMLUnit.setNormalizeWhitespace(true); + } + + @Test + public void addSimpleToEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddClientSSLContext addClientSslContext = new AddClientSSLContext.Builder("clientSslContext").build(); + + assertXmlIdentical(SUBSYSTEM_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addClientSslContext); + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addSimpleToTlsEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_TLS_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddClientSSLContext addClientSslContext = new AddClientSSLContext.Builder("clientSslContext").build(); + + assertXmlIdentical(SUBSYSTEM_TLS_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addClientSslContext); + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addSimpleToClientSslContextEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_CLIENT_SSL_CONTEXTS_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddClientSSLContext addClientSslContext = new AddClientSSLContext.Builder("clientSslContext").build(); + + assertXmlIdentical(SUBSYSTEM_CLIENT_SSL_CONTEXTS_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addClientSslContext); + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test(expected = CommandFailedException.class) + public void existing() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddClientSSLContext addClientSslContext = new AddClientSSLContext.Builder("clientSslContext").build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addClientSslContext); + + fail("Client SSL context clientSslContext already exists in configuration, exception should be thrown"); + } + + @Test + public void overrideExisting() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddClientSSLContext addClientSslContext = new AddClientSSLContext.Builder("clientSslContext") + .cipherSuiteFilter("ALL") + .replaceExisting() + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addClientSslContext); + assertXmlIdentical(SUBSYSTEM_EXPECTED_REPLACE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void overrideNonExisting() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddClientSSLContext addClientSslContext = new AddClientSSLContext.Builder("clientSslContext2") + .replaceExisting() + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addClientSslContext); + assertXmlIdentical(SUBSYSTEM_SECOND_CLIENT_SSL_CONTEXT, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addSecondContext() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddClientSSLContext addClientSslContext = new AddClientSSLContext.Builder("clientSslContext2") + .replaceExisting() + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addClientSslContext); + assertXmlIdentical(SUBSYSTEM_SECOND_CLIENT_SSL_CONTEXT, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addFullToEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddClientSSLContext addClientSslContext = new AddClientSSLContext.Builder("clientSslContext") + .cipherSuiteFilter("ALL") + .keyManager("keyManager") + .trustManager("trustManager") + .protocols("TLSv1.2", "TLSv1.1") + .providerName("ksProvider") + .providers("ksProviderLoader") + .build(); + + assertXmlIdentical(SUBSYSTEM_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addClientSslContext); + assertXmlIdentical(SUBSYSTEM_FULL, Files.toString(cfg, Charsets.UTF_8)); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddClientSSLContextOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddClientSSLContextOnlineTest.java new file mode 100644 index 00000000..ada5097b --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddClientSSLContextOnlineTest.java @@ -0,0 +1,134 @@ +package org.wildfly.extras.creaper.commands.elytron.tls; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddClientSSLContextOnlineTest extends AbstractAddSSLContextOnlineTest { + + private static final String CLIENT_SSL_CONTEXT_PROTOCOL = "TLSv1.2"; + private static final String CLIENT_SSL_CONTEXT_NAME = "CreaperTestCLientSSLContext"; + private static final String CLIENT_SSL_CONTEXT_NAME2 = "CreaperTestCLientSSLContext2"; + private static final Address CLIENT_SSL_CONTEXT_ADDRESS = SUBSYSTEM_ADDRESS.and("client-ssl-context", + CLIENT_SSL_CONTEXT_NAME); + private static final Address CLIENT_SSL_CONTEXT_ADDRESS2 = SUBSYSTEM_ADDRESS.and("client-ssl-context", + CLIENT_SSL_CONTEXT_NAME2); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(CLIENT_SSL_CONTEXT_ADDRESS); + ops.removeIfExists(CLIENT_SSL_CONTEXT_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleClientSSLContext() throws Exception { + AddClientSSLContext addClientSSLContext = new AddClientSSLContext.Builder(CLIENT_SSL_CONTEXT_NAME) + .build(); + assertFalse("The client ssl context should not exist", ops.exists(CLIENT_SSL_CONTEXT_ADDRESS)); + client.apply(addClientSSLContext); + assertTrue("Client ssl context should be created", ops.exists(CLIENT_SSL_CONTEXT_ADDRESS)); + } + + @Test + public void addTwoSimpleClientSSLContexts() throws Exception { + AddClientSSLContext addClientSSLContext = new AddClientSSLContext.Builder(CLIENT_SSL_CONTEXT_NAME) + .build(); + AddClientSSLContext addClientSSLContext2 = new AddClientSSLContext.Builder(CLIENT_SSL_CONTEXT_NAME2) + .build(); + + assertFalse("The client ssl context should not exist", ops.exists(CLIENT_SSL_CONTEXT_ADDRESS)); + assertFalse("The client ssl context should not exist", ops.exists(CLIENT_SSL_CONTEXT_ADDRESS2)); + + client.apply(addClientSSLContext); + client.apply(addClientSSLContext2); + + assertTrue("Client SSL context should be created", ops.exists(CLIENT_SSL_CONTEXT_ADDRESS)); + assertTrue("Client SSL context should be created", ops.exists(CLIENT_SSL_CONTEXT_ADDRESS2)); + } + + @Test(expected = CommandFailedException.class) + public void addDuplicateClientSSLContextNotAllowed() throws Exception { + AddClientSSLContext addClientSSLContext = new AddClientSSLContext.Builder(CLIENT_SSL_CONTEXT_NAME) + .build(); + AddClientSSLContext addClientSSLContext2 = new AddClientSSLContext.Builder(CLIENT_SSL_CONTEXT_NAME) + .build(); + + client.apply(addClientSSLContext); + assertTrue("The client ssl context should be created", ops.exists(CLIENT_SSL_CONTEXT_ADDRESS)); + + client.apply(addClientSSLContext2); + fail("Client ssl context is already configured, exception should be thrown"); + } + + @Test + public void addDuplicateClientSSLContexAllowed() throws Exception { + AddClientSSLContext addClientSSLContext = new AddClientSSLContext.Builder(CLIENT_SSL_CONTEXT_NAME) + .protocols("TLSv1.2") + .build(); + AddClientSSLContext addClientSSLContext2 = new AddClientSSLContext.Builder(CLIENT_SSL_CONTEXT_NAME) + .protocols("TLSv1.1") + .replaceExisting() + .build(); + + client.apply(addClientSSLContext); + assertTrue("The client ssl context should be created", ops.exists(CLIENT_SSL_CONTEXT_ADDRESS)); + + client.apply(addClientSSLContext2); + assertTrue("The cleint ssl context should be created", ops.exists(CLIENT_SSL_CONTEXT_ADDRESS)); + // check whether it was really rewritten + checkAttribute(CLIENT_SSL_CONTEXT_ADDRESS, "protocols", Arrays.asList("TLSv1.1")); + } + + @Test + public void addFullClientSSLContext() throws Exception { + AddClientSSLContext addClientSSLContext = new AddClientSSLContext.Builder(CLIENT_SSL_CONTEXT_NAME) + .cipherSuiteFilter("ALL") + .keyManager(TEST_KEY_MNGR_NAME) + .trustManager(TRUST_MNGR_NAME) + .protocols(CLIENT_SSL_CONTEXT_PROTOCOL) + .build(); + client.apply(addClientSSLContext); + assertTrue("The client ssl context should be created", ops.exists(CLIENT_SSL_CONTEXT_ADDRESS)); + + checkAttribute("cipher-suite-filter", "ALL"); + checkAttribute("key-manager", TEST_KEY_MNGR_NAME); + checkAttribute("trust-manager", TRUST_MNGR_NAME); + checkAttribute("protocols", Arrays.asList(CLIENT_SSL_CONTEXT_PROTOCOL)); + } + + @Test(expected = IllegalArgumentException.class) + public void addClientSSLContext_nullName() throws Exception { + new AddClientSSLContext.Builder(null) + .build(); + fail("Creating command with null client SSL context name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addClientSSLContext_emptyName() throws Exception { + new AddClientSSLContext.Builder("") + .build(); + fail("Creating command with empty client ssl context name should throw exception"); + } + + private void checkAttribute(String attribute, String expectedValue) throws IOException { + checkAttribute(CLIENT_SSL_CONTEXT_ADDRESS, attribute, expectedValue); + } + + private void checkAttribute(String attribute, List expected) throws IOException { + checkAttribute(CLIENT_SSL_CONTEXT_ADDRESS, attribute, expected); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddFilteringKeyStoreOfflineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddFilteringKeyStoreOfflineTest.java new file mode 100644 index 00000000..f8a86080 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddFilteringKeyStoreOfflineTest.java @@ -0,0 +1,227 @@ +package org.wildfly.extras.creaper.commands.elytron.tls; + +import static org.junit.Assert.fail; +import static org.wildfly.extras.creaper.XmlAssert.assertXmlIdentical; +import com.google.common.base.Charsets; +import com.google.common.io.Files; +import java.io.File; +import org.custommonkey.xmlunit.XMLUnit; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.ManagementClient; +import org.wildfly.extras.creaper.core.offline.OfflineManagementClient; +import org.wildfly.extras.creaper.core.offline.OfflineOptions; + +public class AddFilteringKeyStoreOfflineTest { + + private static final String SUBSYSTEM_EMPTY = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_TLS_EMPTY = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_KEY_STORES_EMPTY = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_SIMPLE = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_EXPECTED_REPLACE = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_SECOND_KEY_STORE = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + @Rule + public final TemporaryFolder tmp = new TemporaryFolder(); + + @Before + public void setUp() { + XMLUnit.setNormalizeWhitespace(true); + } + + @Test + public void addSimpleToEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddFilteringKeyStore addKeyStore = new AddFilteringKeyStore.Builder("creaperKeyStore") + .aliasFilter("aliasFilter") + .keyStore("referencedKeyStore") + .build(); + + assertXmlIdentical(SUBSYSTEM_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addKeyStore); + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addSimpleToTlsEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_TLS_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddFilteringKeyStore addKeyStore = new AddFilteringKeyStore.Builder("creaperKeyStore") + .aliasFilter("aliasFilter") + .keyStore("referencedKeyStore") + .build(); + + assertXmlIdentical(SUBSYSTEM_TLS_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addKeyStore); + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addSimpleToKeyStoresEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_KEY_STORES_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddFilteringKeyStore addKeyStore = new AddFilteringKeyStore.Builder("creaperKeyStore") + .aliasFilter("aliasFilter") + .keyStore("referencedKeyStore") + .build(); + + assertXmlIdentical(SUBSYSTEM_KEY_STORES_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addKeyStore); + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test(expected = CommandFailedException.class) + public void existing() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddFilteringKeyStore addKeyStore = new AddFilteringKeyStore.Builder("creaperKeyStore") + .aliasFilter("aliasFilter") + .keyStore("referencedKeyStore") + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addKeyStore); + + fail("Filtering key store creaperKeyStore already exists in configuration, exception should be thrown"); + } + + @Test + public void overrideExisting() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddFilteringKeyStore addKeyStore = new AddFilteringKeyStore.Builder("creaperKeyStore") + .aliasFilter("aliasFilter") + .keyStore("referencedKeyStore2") + .replaceExisting() + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addKeyStore); + assertXmlIdentical(SUBSYSTEM_EXPECTED_REPLACE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void overrideNonExisting() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddFilteringKeyStore addKeyStore = new AddFilteringKeyStore.Builder("creaperKeyStore2") + .aliasFilter("aliasFilter") + .keyStore("referencedKeyStore") + .replaceExisting() + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addKeyStore); + assertXmlIdentical(SUBSYSTEM_SECOND_KEY_STORE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addSecondKeyStore() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddFilteringKeyStore addKeyStore = new AddFilteringKeyStore.Builder("creaperKeyStore2") + .aliasFilter("aliasFilter") + .keyStore("referencedKeyStore") + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addKeyStore); + assertXmlIdentical(SUBSYSTEM_SECOND_KEY_STORE, Files.toString(cfg, Charsets.UTF_8)); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddFilteringKeyStoreOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddFilteringKeyStoreOnlineTest.java new file mode 100644 index 00000000..b1047dae --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddFilteringKeyStoreOnlineTest.java @@ -0,0 +1,203 @@ +package org.wildfly.extras.creaper.commands.elytron.tls; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.commands.elytron.CredentialRef; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.OnlineManagementClient; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +@RunWith(Arquillian.class) +public class AddFilteringKeyStoreOnlineTest extends AbstractElytronOnlineTest { + + private static final String KEY_STORE_NAME = "CreaperTestKeyStore"; + private static final Address KEY_STORE_ADDRESS = SUBSYSTEM_ADDRESS.and("key-store", KEY_STORE_NAME); + private static final String KEY_STORE_TYPE = "JKS"; + private static final String TEST_KEY_STORE_PASSWORD = "password"; + + private static final String FILTERING_KEY_STORE_NAME = "CreaperTestFilteringKeyStore"; + private static final String FILTERING_KEY_STORE_NAME2 = "CreaperTestFilteringKeyStore2"; + private static final Address FILTERING_KEY_STORE_ADDRESS = SUBSYSTEM_ADDRESS.and("filtering-key-store", + FILTERING_KEY_STORE_NAME); + private static final Address FILTERING_KEY_STORE_ADDRESS2 = SUBSYSTEM_ADDRESS.and("filtering-key-store", + FILTERING_KEY_STORE_NAME2); + private static final String ALIAS_FILTER = "alias"; + private static final String ALIAS_FILTER2 = "alias2"; + + @BeforeClass + public static void addKeyStores() throws Exception { + OnlineManagementClient client = null; + try { + client = createManagementClient(); + AddKeyStore addKeyStore = new AddKeyStore.Builder(KEY_STORE_NAME) + .type(KEY_STORE_TYPE) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_STORE_PASSWORD) + .build()) + .build(); + client.apply(addKeyStore); + } finally { + if (client != null) { + client.close(); + } + } + } + + @AfterClass + public static void removeKeyStores() throws Exception { + OnlineManagementClient client = null; + try { + client = createManagementClient(); + Operations ops = new Operations(client); + Administration administration = new Administration(client); + ops.removeIfExists(KEY_STORE_ADDRESS); + administration.reloadIfRequired(); + } finally { + if (client != null) { + client.close(); + } + } + } + + @After + public void cleanup() throws Exception { + ops.removeIfExists(FILTERING_KEY_STORE_ADDRESS); + ops.removeIfExists(FILTERING_KEY_STORE_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleFilteringKeyStore() throws Exception { + AddFilteringKeyStore addFilteringKeyStore = new AddFilteringKeyStore.Builder(FILTERING_KEY_STORE_NAME) + .keyStore(KEY_STORE_NAME) + .aliasFilter(ALIAS_FILTER) + .build(); + assertFalse("The filtering key store should not exist", ops.exists(FILTERING_KEY_STORE_ADDRESS)); + client.apply(addFilteringKeyStore); + assertTrue("Filtering key store should be created", ops.exists(FILTERING_KEY_STORE_ADDRESS)); + } + + @Test + public void addTwoSimpleFilteringKeyStores() throws Exception { + AddFilteringKeyStore addFilteringKeyStore = new AddFilteringKeyStore.Builder(FILTERING_KEY_STORE_NAME) + .keyStore(KEY_STORE_NAME) + .aliasFilter(ALIAS_FILTER) + .build(); + AddFilteringKeyStore addFilteringKeyStore2 = new AddFilteringKeyStore.Builder(FILTERING_KEY_STORE_NAME2) + .keyStore(KEY_STORE_NAME) + .aliasFilter(ALIAS_FILTER) + .build(); + + assertFalse("The filtering key store should not exist", ops.exists(FILTERING_KEY_STORE_ADDRESS)); + assertFalse("The filtering key store should not exist", ops.exists(FILTERING_KEY_STORE_ADDRESS2)); + + client.apply(addFilteringKeyStore); + client.apply(addFilteringKeyStore2); + + assertTrue("Filtering key store should be created", ops.exists(FILTERING_KEY_STORE_ADDRESS)); + assertTrue("Filtering key store should be created", ops.exists(FILTERING_KEY_STORE_ADDRESS2)); + } + + @Test(expected = CommandFailedException.class) + public void addDuplicatefilteringKeyStoreNotAllowed() throws Exception { + AddFilteringKeyStore addFilteringKeyStore = new AddFilteringKeyStore.Builder(FILTERING_KEY_STORE_NAME) + .keyStore(KEY_STORE_NAME) + .aliasFilter(ALIAS_FILTER) + .build(); + AddFilteringKeyStore addFilteringKeyStore2 = new AddFilteringKeyStore.Builder(FILTERING_KEY_STORE_NAME) + .keyStore(KEY_STORE_NAME) + .aliasFilter(ALIAS_FILTER) + .build(); + + client.apply(addFilteringKeyStore); + assertTrue("The filtering key store should be created", ops.exists(FILTERING_KEY_STORE_ADDRESS)); + + client.apply(addFilteringKeyStore2); + fail("Filtering key store is already configured, exception should be thrown"); + } + + @Test + public void addDuplicateFilteringKeyStoreAllowed() throws Exception { + AddFilteringKeyStore addFilteringKeyStore = new AddFilteringKeyStore.Builder(FILTERING_KEY_STORE_NAME) + .keyStore(KEY_STORE_NAME) + .aliasFilter(ALIAS_FILTER) + .build(); + AddFilteringKeyStore addFilteringKeyStore2 = new AddFilteringKeyStore.Builder(FILTERING_KEY_STORE_NAME) + .keyStore(KEY_STORE_NAME) + .aliasFilter(ALIAS_FILTER2) + .replaceExisting() + .build(); + client.apply(addFilteringKeyStore); + assertTrue("The filtering key store should be created", ops.exists(FILTERING_KEY_STORE_ADDRESS)); + + client.apply(addFilteringKeyStore2); + assertTrue("The filtering key store should be created", ops.exists(FILTERING_KEY_STORE_ADDRESS)); + checkAttribute(FILTERING_KEY_STORE_ADDRESS, "alias-filter", ALIAS_FILTER2); + } + + @Test(expected = IllegalArgumentException.class) + public void addFilteringKeyStore_nullName() throws Exception { + AddFilteringKeyStore addFilteringKeyStore = new AddFilteringKeyStore.Builder(null) + .keyStore(KEY_STORE_NAME) + .aliasFilter(ALIAS_FILTER) + .build(); + fail("Creating command with null filtering keystore name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addKeyStore_emptyName() throws Exception { + AddFilteringKeyStore addFilteringKeyStore = new AddFilteringKeyStore.Builder("") + .keyStore(KEY_STORE_NAME) + .aliasFilter(ALIAS_FILTER) + .build(); + fail("Creating command with empty filtering keystore name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addFilteringKeyStore_nullKeyStore() throws Exception { + AddFilteringKeyStore addFilteringKeyStore = new AddFilteringKeyStore.Builder(FILTERING_KEY_STORE_NAME) + .keyStore(null) + .aliasFilter(ALIAS_FILTER) + .build(); + fail("Creating command with null filtering keystore keystore should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addKeyStore_emptyKeyStore() throws Exception { + AddFilteringKeyStore addFilteringKeyStore = new AddFilteringKeyStore.Builder(FILTERING_KEY_STORE_NAME) + .keyStore("") + .aliasFilter(ALIAS_FILTER) + .build(); + fail("Creating command with empty filtering keystore keystore should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addFilteringKeyStore_nullFilterAlias() throws Exception { + AddFilteringKeyStore addFilteringKeyStore = new AddFilteringKeyStore.Builder(FILTERING_KEY_STORE_NAME) + .keyStore(KEY_STORE_NAME) + .aliasFilter(null) + .build(); + fail("Creating command with null filtering keystore filter alias should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addKeyStore_emptyFilterAlias() throws Exception { + AddFilteringKeyStore addFilteringKeyStore = new AddFilteringKeyStore.Builder(FILTERING_KEY_STORE_NAME) + .keyStore(KEY_STORE_NAME) + .aliasFilter("") + .build(); + fail("Creating command with empty filtering keystore filter alias should throw exception"); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyManagerOfflineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyManagerOfflineTest.java new file mode 100644 index 00000000..1e721368 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyManagerOfflineTest.java @@ -0,0 +1,281 @@ +package org.wildfly.extras.creaper.commands.elytron.tls; + +import static org.junit.Assert.fail; +import static org.wildfly.extras.creaper.XmlAssert.assertXmlIdentical; + +import java.io.File; + +import org.custommonkey.xmlunit.XMLUnit; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.wildfly.extras.creaper.commands.elytron.CredentialRef.CredentialRefBuilder; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.ManagementClient; +import org.wildfly.extras.creaper.core.offline.OfflineManagementClient; +import org.wildfly.extras.creaper.core.offline.OfflineOptions; + +import com.google.common.base.Charsets; +import com.google.common.io.Files; + +public class AddKeyManagerOfflineTest { + + private static final String SUBSYSTEM_EMPTY = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_TLS_EMPTY = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_KEY_MANAGERS_EMPTY = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_SIMPLE = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_EXPECTED_REPLACE = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_SECOND_KEY_MANAGER = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_FULL = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + @Rule + public final TemporaryFolder tmp = new TemporaryFolder(); + + @Before + public void setUp() { + XMLUnit.setNormalizeWhitespace(true); + } + + @Test + public void addSimpleToEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddKeyManager addKeyManager = new AddKeyManager.Builder("creaperKeyManager") + .keyStore("someKeyStore") + .credentialReference(new CredentialRefBuilder().clearText("secret").build()) + .build(); + + assertXmlIdentical(SUBSYSTEM_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addKeyManager); + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addSimpleToTlsEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_TLS_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddKeyManager addKeyManager = new AddKeyManager.Builder("creaperKeyManager") + .keyStore("someKeyStore") + .credentialReference(new CredentialRefBuilder().clearText("secret").build()) + .build(); + + assertXmlIdentical(SUBSYSTEM_TLS_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addKeyManager); + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addSimpleToKeyManagerEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_KEY_MANAGERS_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddKeyManager addKeyManager = new AddKeyManager.Builder("creaperKeyManager") + .keyStore("someKeyStore") + .credentialReference(new CredentialRefBuilder().clearText("secret").build()) + .build(); + + assertXmlIdentical(SUBSYSTEM_KEY_MANAGERS_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addKeyManager); + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test(expected = CommandFailedException.class) + public void existing() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddKeyManager addKeyManager = new AddKeyManager.Builder("creaperKeyManager") + .keyStore("someKeyStore") + .credentialReference(new CredentialRefBuilder().clearText("secret").build()) + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addKeyManager); + + fail("Key manager creaperKeyManager already exists in configuration, exception should be thrown"); + } + + @Test + public void overrideExisting() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddKeyManager addKeyManager = new AddKeyManager.Builder("creaperKeyManager") + .keyStore("someKeyStore") + .credentialReference(new CredentialRefBuilder().clearText("secret2").build()) + .replaceExisting() + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addKeyManager); + assertXmlIdentical(SUBSYSTEM_EXPECTED_REPLACE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void overrideNonExisting() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddKeyManager addKeyManager = new AddKeyManager.Builder("creaperKeyManager2") + .keyStore("someKeyStore") + .credentialReference(new CredentialRefBuilder().clearText("secret").build()) + .replaceExisting() + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addKeyManager); + assertXmlIdentical(SUBSYSTEM_SECOND_KEY_MANAGER, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addSecondKeyManager() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddKeyManager addKeyManager = new AddKeyManager.Builder("creaperKeyManager2") + .keyStore("someKeyStore") + .credentialReference(new CredentialRefBuilder().clearText("secret").build()) + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addKeyManager); + assertXmlIdentical(SUBSYSTEM_SECOND_KEY_MANAGER, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addFullToEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddKeyManager addKeyManager = new AddKeyManager.Builder("creaperKeyManager") + .algorithm("SunX509") + .aliasFilter("aliasInFilter") + .keyStore("someKeyStore") + .providerName("ksProvider") + .providers("ksProviderLoader") + .credentialReference(new CredentialRefBuilder() + .alias("crAlias") + .type("crType") + .store("crStore") + .clearText("secret") + .build()) + .build(); + + assertXmlIdentical(SUBSYSTEM_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addKeyManager); + assertXmlIdentical(SUBSYSTEM_FULL, Files.toString(cfg, Charsets.UTF_8)); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyManagerOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyManagerOnlineTest.java new file mode 100644 index 00000000..40be5edb --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyManagerOnlineTest.java @@ -0,0 +1,255 @@ +package org.wildfly.extras.creaper.commands.elytron.tls; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; + +import javax.net.ssl.KeyManagerFactory; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.commands.elytron.CredentialRef; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.OnlineManagementClient; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +@RunWith(Arquillian.class) +public class AddKeyManagerOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_KEY_STORE_NAME = "CreaperTestKeyStore"; + private static final String TEST_KEY_STORE_NAME2 = "CreaperTestKeyStore2"; + private static final Address TEST_KEY_STORE_ADDRESS = SUBSYSTEM_ADDRESS.and("key-store", TEST_KEY_STORE_NAME); + private static final Address TEST_KEY_STORE_ADDRESS2 = SUBSYSTEM_ADDRESS.and("key-store", TEST_KEY_STORE_NAME2); + private static final String TEST_KEY_STORE_TYPE = "JKS"; + private static final String TEST_KEY_STORE_PASSWORD = "password"; + private static final String TEST_KEY_PASSWORD = "password"; + + private static final String TEST_KEY_MNGR_NAME = "CreaperTestKeyManager"; + private static final String TEST_KEY_MNGR_NAME2 = "CreaperTestKeyManager2"; + private static final Address TEST_KEY_MNGR_ADDRESS = SUBSYSTEM_ADDRESS.and("key-manager", TEST_KEY_MNGR_NAME); + private static final Address TEST_KEY_MNGR_ADDRESS2 = SUBSYSTEM_ADDRESS.and("key-manager", TEST_KEY_MNGR_NAME2); + private static final String TEST_KEY_MANAGER_ALGORITHM = KeyManagerFactory.getDefaultAlgorithm(); + + @BeforeClass + public static void addKeyStores() throws Exception { + OnlineManagementClient client = null; + try { + client = createManagementClient(); + AddKeyStore addKeyStore = new AddKeyStore.Builder(TEST_KEY_STORE_NAME) + .type(TEST_KEY_STORE_TYPE) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_STORE_PASSWORD) + .build()) + .build(); + AddKeyStore addKeyStore2 = new AddKeyStore.Builder(TEST_KEY_STORE_NAME2) + .type(TEST_KEY_STORE_TYPE) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_STORE_PASSWORD) + .build()) + .build(); + + client.apply(addKeyStore); + client.apply(addKeyStore2); + } finally { + if (client != null) { + client.close(); + } + } + } + + @AfterClass + public static void removeKeyStores() throws Exception { + OnlineManagementClient client = null; + try { + client = createManagementClient(); + Operations ops = new Operations(client); + Administration administration = new Administration(client); + ops.removeIfExists(TEST_KEY_STORE_ADDRESS); + ops.removeIfExists(TEST_KEY_STORE_ADDRESS2); + administration.reloadIfRequired(); + } finally { + if (client != null) { + client.close(); + } + } + } + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_KEY_MNGR_ADDRESS); + ops.removeIfExists(TEST_KEY_MNGR_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleKeyManager() throws Exception { + AddKeyManager addKeyManager = new AddKeyManager.Builder(TEST_KEY_MNGR_NAME) + .keyStore(TEST_KEY_STORE_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_PASSWORD) + .build()) + .build(); + assertFalse("The key manager should not exist", ops.exists(TEST_KEY_MNGR_ADDRESS)); + client.apply(addKeyManager); + assertTrue("Key manager should be created", ops.exists(TEST_KEY_MNGR_ADDRESS)); + } + + @Test + public void addTwoSimpleKeyManagers() throws Exception { + AddKeyManager addKeyManager = new AddKeyManager.Builder(TEST_KEY_MNGR_NAME) + .keyStore(TEST_KEY_STORE_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_PASSWORD) + .build()) + .build(); + AddKeyManager addKeyManager2 = new AddKeyManager.Builder(TEST_KEY_MNGR_NAME2) + .keyStore(TEST_KEY_STORE_NAME2) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_PASSWORD) + .build()) + .build(); + + assertFalse("The key manager should not exist", ops.exists(TEST_KEY_MNGR_ADDRESS)); + assertFalse("The key manager should not exist", ops.exists(TEST_KEY_MNGR_ADDRESS2)); + + client.apply(addKeyManager); + client.apply(addKeyManager2); + + assertTrue("Key manager should be created", ops.exists(TEST_KEY_MNGR_ADDRESS)); + assertTrue("Key manager should be created", ops.exists(TEST_KEY_MNGR_ADDRESS2)); + } + + @Test(expected = CommandFailedException.class) + public void addDuplicateKeyManagersNotAllowed() throws Exception { + AddKeyManager addKeyManager = new AddKeyManager.Builder(TEST_KEY_MNGR_NAME) + .keyStore(TEST_KEY_STORE_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_PASSWORD) + .build()) + .build(); + AddKeyManager addKeyManager2 = new AddKeyManager.Builder(TEST_KEY_MNGR_NAME) + .keyStore(TEST_KEY_STORE_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_PASSWORD) + .build()) + .build(); + + client.apply(addKeyManager); + assertTrue("The key manager should be created", ops.exists(TEST_KEY_MNGR_ADDRESS)); + + client.apply(addKeyManager2); + fail("Key manager is already configured, exception should be thrown"); + } + + @Test + public void addDuplicateKeyManagerAllowed() throws Exception { + AddKeyManager addKeyManager = new AddKeyManager.Builder(TEST_KEY_MNGR_NAME) + .keyStore(TEST_KEY_STORE_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_PASSWORD) + .build()) + .build(); + AddKeyManager addKeyManager2 = new AddKeyManager.Builder(TEST_KEY_MNGR_NAME) + .keyStore(TEST_KEY_STORE_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("test-Password") + .build()) + .replaceExisting() + .build(); + + client.apply(addKeyManager); + assertTrue("The key manager should be created", ops.exists(TEST_KEY_MNGR_ADDRESS)); + + client.apply(addKeyManager2); + assertTrue("The key manager should be created", ops.exists(TEST_KEY_MNGR_ADDRESS)); + // check whether it was really rewritten + checkAttributeObject(TEST_KEY_MNGR_ADDRESS, "credential-reference", "clear-text", "test-Password"); + + } + + @Test + public void addFullKeyManager() throws Exception { + AddKeyManager addKeyManager = new AddKeyManager.Builder(TEST_KEY_MNGR_NAME) + .algorithm(TEST_KEY_MANAGER_ALGORITHM) + .aliasFilter("server-alias") + .keyStore(TEST_KEY_STORE_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_PASSWORD) + .build()) + .build(); + client.apply(addKeyManager); + assertTrue("Key manager should be created", ops.exists(TEST_KEY_MNGR_ADDRESS)); + + checkAttribute("algorithm", TEST_KEY_MANAGER_ALGORITHM); + checkAttribute("alias-filter", "server-alias"); + checkAttribute("key-store", TEST_KEY_STORE_NAME); + checkAttributeObject(TEST_KEY_MNGR_ADDRESS, "credential-reference", "clear-text", TEST_KEY_PASSWORD); + } + + @Test(expected = IllegalArgumentException.class) + public void addKeyManager_nullName() throws Exception { + new AddKeyManager.Builder(null) + .keyStore(TEST_KEY_STORE_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_PASSWORD) + .build()) + .build(); + fail("Creating command with null key manager name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addKeyManager_emptyName() throws Exception { + new AddKeyManager.Builder("") + .keyStore(TEST_KEY_STORE_NAME) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_PASSWORD) + .build()) + .build(); + fail("Creating command with empty key manager name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addKeyManager_nullKeyPassword() throws Exception { + new AddKeyManager.Builder(TEST_KEY_MNGR_NAME) + .keyStore(TEST_KEY_STORE_NAME) + .credentialReference(null) + .build(); + fail("Creating command with null key password name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addKeyManager_nullKeyStore() throws Exception { + new AddKeyManager.Builder(TEST_KEY_MNGR_NAME) + .keyStore(null) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_PASSWORD) + .build()) + .build(); + fail("Creating command with null key password name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addKeyManager_emptyKeyStore() throws Exception { + new AddKeyManager.Builder(TEST_KEY_MNGR_NAME) + .keyStore("") + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_PASSWORD) + .build()) + .build(); + fail("Creating command with null key password name should throw exception"); + } + + private void checkAttribute(String attribute, String expectedValue) throws IOException { + checkAttribute(TEST_KEY_MNGR_ADDRESS, attribute, expectedValue); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyStoreOfflineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyStoreOfflineTest.java new file mode 100644 index 00000000..78c03a81 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyStoreOfflineTest.java @@ -0,0 +1,288 @@ +package org.wildfly.extras.creaper.commands.elytron.tls; + +import static org.junit.Assert.fail; +import static org.wildfly.extras.creaper.XmlAssert.assertXmlIdentical; + +import com.google.common.base.Charsets; +import com.google.common.io.Files; +import java.io.File; +import org.custommonkey.xmlunit.XMLUnit; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.wildfly.extras.creaper.commands.elytron.CredentialRef.CredentialRefBuilder; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.ManagementClient; +import org.wildfly.extras.creaper.core.offline.OfflineManagementClient; +import org.wildfly.extras.creaper.core.offline.OfflineOptions; + +public class AddKeyStoreOfflineTest { + + private static final String SUBSYSTEM_EMPTY = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_TLS_EMPTY = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_KEY_STORES_EMPTY = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_SIMPLE = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_EXPECTED_REPLACE = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_SECOND_KEY_STORE = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_FULL = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + @Rule + public final TemporaryFolder tmp = new TemporaryFolder(); + + @Before + public void setUp() { + XMLUnit.setNormalizeWhitespace(true); + } + + @Test + public void addSimpleToEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddKeyStore addKeyStore = new AddKeyStore.Builder("creaperKeyStore") + .type("jks") + .credentialReference(new CredentialRefBuilder().clearText("secret").build()) + .build(); + + assertXmlIdentical(SUBSYSTEM_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addKeyStore); + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addSimpleToTlsEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_TLS_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddKeyStore addKeyStore = new AddKeyStore.Builder("creaperKeyStore") + .type("jks") + .credentialReference(new CredentialRefBuilder().clearText("secret").build()) + .build(); + + assertXmlIdentical(SUBSYSTEM_TLS_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addKeyStore); + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addSimpleToKeyStoresEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_KEY_STORES_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddKeyStore addKeyStore = new AddKeyStore.Builder("creaperKeyStore") + .type("jks") + .credentialReference(new CredentialRefBuilder().clearText("secret").build()) + .build(); + + assertXmlIdentical(SUBSYSTEM_KEY_STORES_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addKeyStore); + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test(expected = CommandFailedException.class) + public void existing() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddKeyStore addKeyStore = new AddKeyStore.Builder("creaperKeyStore") + .type("jks") + .credentialReference(new CredentialRefBuilder().clearText("secret").build()) + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addKeyStore); + + fail("Key store creaperKeyStore already exists in configuration, exception should be thrown"); + } + + @Test + public void overrideExisting() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddKeyStore addKeyStore = new AddKeyStore.Builder("creaperKeyStore") + .type("jks") + .path("/tmp/keystore.jks") + .credentialReference(new CredentialRefBuilder().clearText("secret").build()) + .replaceExisting() + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addKeyStore); + assertXmlIdentical(SUBSYSTEM_EXPECTED_REPLACE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void overrideNonExisting() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddKeyStore addKeyStore = new AddKeyStore.Builder("creaperKeyStore2") + .type("jks") + .credentialReference(new CredentialRefBuilder().clearText("secret").build()) + .replaceExisting() + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addKeyStore); + assertXmlIdentical(SUBSYSTEM_SECOND_KEY_STORE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addSecondKeyStore() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddKeyStore addKeyStore = new AddKeyStore.Builder("creaperKeyStore2") + .type("jks") + .credentialReference(new CredentialRefBuilder().clearText("secret").build()) + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addKeyStore); + assertXmlIdentical(SUBSYSTEM_SECOND_KEY_STORE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addFullToEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddKeyStore addKeyStore = new AddKeyStore.Builder("creaperKeyStore") + .type("jks") + .providerName("ksProvider") + .providers("ksProviderLoader") + .aliasFilter("aliasInFilter") + .path("/tmp/keystore.jks") + .relativeTo("relativeToDir") + .required(true) + .credentialReference(new CredentialRefBuilder() + .alias("crAlias") + .type("crType") + .store("crStore") + .clearText("secret") + .build()) + .build(); + + assertXmlIdentical(SUBSYSTEM_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addKeyStore); + assertXmlIdentical(SUBSYSTEM_FULL, Files.toString(cfg, Charsets.UTF_8)); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyStoreOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyStoreOnlineTest.java new file mode 100644 index 00000000..f834d17b --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddKeyStoreOnlineTest.java @@ -0,0 +1,195 @@ +package org.wildfly.extras.creaper.commands.elytron.tls; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.commands.elytron.CredentialRef; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddKeyStoreOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_KEY_STORE_NAME = "CreaperTestKeyStore"; + private static final String TEST_KEY_STORE_NAME2 = "CreaperTestKeyStore2"; + private static final String TEST_KEY_STORE_TYPE = "JKS"; + private static final String TEST_KEY_STORE_PASSWORD = "password"; + private static final Address TEST_KEY_STORE_ADDRESS = SUBSYSTEM_ADDRESS.and("key-store", TEST_KEY_STORE_NAME); + private static final Address TEST_KEY_STORE_ADDRESS2 = SUBSYSTEM_ADDRESS.and("key-store", TEST_KEY_STORE_NAME2); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_KEY_STORE_ADDRESS); + ops.removeIfExists(TEST_KEY_STORE_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleKeyStore() throws Exception { + AddKeyStore addKeyStore = new AddKeyStore.Builder(TEST_KEY_STORE_NAME) + .type(TEST_KEY_STORE_TYPE) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_STORE_PASSWORD) + .build()) + .build(); + assertFalse("The key store should not exist", ops.exists(TEST_KEY_STORE_ADDRESS)); + client.apply(addKeyStore); + assertTrue("Key store should be created", ops.exists(TEST_KEY_STORE_ADDRESS)); + } + + @Test + public void addTwoSimpleKeyStores() throws Exception { + AddKeyStore addKeyStore = new AddKeyStore.Builder(TEST_KEY_STORE_NAME) + .type(TEST_KEY_STORE_TYPE) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_STORE_PASSWORD) + .build()) + .build(); + AddKeyStore addKeyStore2 = new AddKeyStore.Builder(TEST_KEY_STORE_NAME2) + .type(TEST_KEY_STORE_TYPE) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_STORE_PASSWORD) + .build()) + .build(); + + assertFalse("The key store should not exist", ops.exists(TEST_KEY_STORE_ADDRESS)); + assertFalse("The key store should not exist", ops.exists(TEST_KEY_STORE_ADDRESS2)); + + client.apply(addKeyStore); + client.apply(addKeyStore2); + + assertTrue("Key store should be created", ops.exists(TEST_KEY_STORE_ADDRESS)); + assertTrue("Key store should be created", ops.exists(TEST_KEY_STORE_ADDRESS2)); + } + + @Test(expected = CommandFailedException.class) + public void addExistKeyStoreNotAllowed() throws Exception { + AddKeyStore addKeyStore = new AddKeyStore.Builder(TEST_KEY_STORE_NAME) + .type(TEST_KEY_STORE_TYPE) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_STORE_PASSWORD) + .build()) + .build(); + AddKeyStore addKeyStore2 = new AddKeyStore.Builder(TEST_KEY_STORE_NAME) + .type(TEST_KEY_STORE_TYPE) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_STORE_PASSWORD) + .build()) + .build(); + + client.apply(addKeyStore); + assertTrue("The key store should be created", ops.exists(TEST_KEY_STORE_ADDRESS)); + + client.apply(addKeyStore2); + fail("Key store is already configured, exception should be thrown"); + } + + @Test + public void addExistKeyStoreAllowed() throws Exception { + AddKeyStore addKeyStore = new AddKeyStore.Builder(TEST_KEY_STORE_NAME) + .type(TEST_KEY_STORE_TYPE) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_STORE_PASSWORD) + .build()) + .build(); + AddKeyStore addKeyStore2 = new AddKeyStore.Builder(TEST_KEY_STORE_NAME) + .type(TEST_KEY_STORE_TYPE) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_STORE_PASSWORD) + .build()) + .aliasFilter("alias") + .replaceExisting() + .build(); + + client.apply(addKeyStore); + assertTrue("The key store should be created", ops.exists(TEST_KEY_STORE_ADDRESS)); + + client.apply(addKeyStore2); + assertTrue("The key store should be created", ops.exists(TEST_KEY_STORE_ADDRESS)); + // check whether it was really rewritten + checkAttribute(TEST_KEY_STORE_ADDRESS, "alias-filter", "alias"); + } + + @Test + public void addFullKeyStore() throws Exception { + AddKeyStore addKeyStore = new AddKeyStore.Builder(TEST_KEY_STORE_NAME) + .type(TEST_KEY_STORE_TYPE) + .aliasFilter("server-alias") + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_STORE_PASSWORD) + .build()) + .build(); + client.apply(addKeyStore); + assertTrue("Key store should be created", ops.exists(TEST_KEY_STORE_ADDRESS)); + + checkAttribute("type", TEST_KEY_STORE_TYPE); + checkAttributeObject(TEST_KEY_STORE_ADDRESS, "credential-reference", "clear-text", TEST_KEY_STORE_PASSWORD); + checkAttribute("alias-filter", "server-alias"); + } + + @Test(expected = IllegalArgumentException.class) + public void addKeyStore_nullName() throws Exception { + new AddKeyStore.Builder(null) + .type(TEST_KEY_STORE_TYPE) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_STORE_PASSWORD) + .build()) + .build(); + fail("Creating command with null keystore name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addKeyStore_emptyName() throws Exception { + new AddKeyStore.Builder("") + .type(TEST_KEY_STORE_TYPE) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_STORE_PASSWORD) + .build()) + .build(); + fail("Creating command with empty keystore name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addKeyStore_nullType() throws Exception { + new AddKeyStore.Builder(TEST_KEY_STORE_NAME) + .type(null) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_STORE_PASSWORD) + .build()) + .build(); + fail("Creating command with null keystore type should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addKeyStore_emptyType() throws Exception { + new AddKeyStore.Builder(TEST_KEY_STORE_NAME) + .type("") + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_STORE_PASSWORD) + .build()) + .build(); + fail("Creating command with empty keystore type should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addKeyStore_nullCredentialRef() throws Exception { + new AddKeyStore.Builder(TEST_KEY_STORE_NAME) + .type(TEST_KEY_STORE_TYPE) + .credentialReference(null) + .build(); + fail("Creating command with null credential ref should throw exception"); + } + + private void checkAttribute(String attribute, String expectedValue) throws IOException { + checkAttribute(TEST_KEY_STORE_ADDRESS, attribute, expectedValue); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddLdapKeyStoreOfflineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddLdapKeyStoreOfflineTest.java new file mode 100644 index 00000000..cb519208 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddLdapKeyStoreOfflineTest.java @@ -0,0 +1,300 @@ +package org.wildfly.extras.creaper.commands.elytron.tls; + +import static org.junit.Assert.fail; +import static org.wildfly.extras.creaper.XmlAssert.assertXmlIdentical; + +import com.google.common.base.Charsets; +import com.google.common.io.Files; +import java.io.File; +import org.custommonkey.xmlunit.XMLUnit; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.wildfly.extras.creaper.commands.elytron.tls.AddLdapKeyStore.NewItemAttributeBuilder; +import org.wildfly.extras.creaper.commands.elytron.tls.AddLdapKeyStore.NewItemTemplateBuilder; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.ManagementClient; +import org.wildfly.extras.creaper.core.offline.OfflineManagementClient; +import org.wildfly.extras.creaper.core.offline.OfflineOptions; + +public class AddLdapKeyStoreOfflineTest { + + private static final String SUBSYSTEM_EMPTY = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_TLS_EMPTY = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_KEY_STORES_EMPTY = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_SIMPLE = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_EXPECTED_REPLACE = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_SECOND_KEY_STORE = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_FULL = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + @Rule + public final TemporaryFolder tmp = new TemporaryFolder(); + + @Before + public void setUp() { + XMLUnit.setNormalizeWhitespace(true); + } + + @Test + public void addSimpleToEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddLdapKeyStore addLdapKeyStore = new AddLdapKeyStore.Builder("creaperKeyStore") + .dirContext("dirContext") + .searchPath("searchPath") + .build(); + + assertXmlIdentical(SUBSYSTEM_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addLdapKeyStore); + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addSimpleToTlsEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_TLS_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddLdapKeyStore addLdapKeyStore = new AddLdapKeyStore.Builder("creaperKeyStore") + .dirContext("dirContext") + .searchPath("searchPath") + .build(); + + assertXmlIdentical(SUBSYSTEM_TLS_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addLdapKeyStore); + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addSimpleToKeyStoresEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_KEY_STORES_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddLdapKeyStore addLdapKeyStore = new AddLdapKeyStore.Builder("creaperKeyStore") + .dirContext("dirContext") + .searchPath("searchPath") + .build(); + + assertXmlIdentical(SUBSYSTEM_KEY_STORES_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addLdapKeyStore); + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test(expected = CommandFailedException.class) + public void existing() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddLdapKeyStore addLdapKeyStore = new AddLdapKeyStore.Builder("creaperKeyStore") + .dirContext("dirContext") + .searchPath("searchPath2") + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addLdapKeyStore); + + fail("LDAP key store creaperKeyStore already exists in configuration, exception should be thrown"); + } + + @Test + public void overrideExisting() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddLdapKeyStore addLdapKeyStore = new AddLdapKeyStore.Builder("creaperKeyStore") + .dirContext("dirContext") + .searchPath("searchPath2") + .replaceExisting() + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addLdapKeyStore); + assertXmlIdentical(SUBSYSTEM_EXPECTED_REPLACE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void overrideNonExisting() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddLdapKeyStore addLdapKeyStore = new AddLdapKeyStore.Builder("creaperKeyStore2") + .dirContext("dirContext") + .searchPath("searchPath") + .replaceExisting() + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addLdapKeyStore); + assertXmlIdentical(SUBSYSTEM_SECOND_KEY_STORE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addSecondKeyStore() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddLdapKeyStore addLdapKeyStore = new AddLdapKeyStore.Builder("creaperKeyStore2") + .dirContext("dirContext") + .searchPath("searchPath") + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addLdapKeyStore); + assertXmlIdentical(SUBSYSTEM_SECOND_KEY_STORE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addFullToEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddLdapKeyStore addLdapKeyStore = new AddLdapKeyStore.Builder("creaperKeyStore") + .dirContext("dirContext") + .searchPath("searchPath") + .searchRecursive(true) + .searchTimeLimit(30) + .filterAlias("filterAlias") + .filterCertificate("filterCertificate") + .filterIterate("filterIterate") + .aliasAttribute("aliasAttribute") + .certificateAttribute("certificateAttribute") + .certificateType("certificateType") + .certificateChainAttribute("certificateChainAttribute") + .certificateChainEncoding("certificateChainEncoding") + .keyAttribute("someKeyAttribute") + .keyType("someKeyType") + .newItemTemplate(new NewItemTemplateBuilder() + .addNewItemAttributes( + new NewItemAttributeBuilder().name("attrA").addValues("valueA").build(), + new NewItemAttributeBuilder().name("attrB").addValues("valueB1", "valueB2").build()) + .newItemPath("newItemPath") + .newItemRdn("newItemRdn") + .build()) + .build(); + + assertXmlIdentical(SUBSYSTEM_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addLdapKeyStore); + assertXmlIdentical(SUBSYSTEM_FULL, Files.toString(cfg, Charsets.UTF_8)); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddLdapKeyStoreOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddLdapKeyStoreOnlineTest.java new file mode 100644 index 00000000..b542f36e --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddLdapKeyStoreOnlineTest.java @@ -0,0 +1,306 @@ +package org.wildfly.extras.creaper.commands.elytron.tls; + +import static org.junit.Assert.fail; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.commands.elytron.CredentialRef; +import org.wildfly.extras.creaper.commands.elytron.dircontext.AddDirContext; +import org.wildfly.extras.creaper.commands.elytron.tls.AddLdapKeyStore.NewItemAttributeBuilder; +import org.wildfly.extras.creaper.commands.elytron.tls.AddLdapKeyStore.NewItemTemplateBuilder; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.operations.Address; + +@RunWith(Arquillian.class) +public class AddLdapKeyStoreOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_DIR_CONTEXT_NAME = "CreaperTestDirContext"; + private static final Address TEST_DIR_CONTEXT_ADDRESS = SUBSYSTEM_ADDRESS.and("dir-context", + TEST_DIR_CONTEXT_NAME); + private static final String TEST_LDAP_KEY_STORE_NAME = "CreaperTestLdapKeyStore"; + private static final String TEST_LDAP_KEY_STORE_NAME2 = "CreaperTestLdapKeyStore2"; + private static final Address TEST_LDAP_KEY_STORE_ADDRESS = SUBSYSTEM_ADDRESS .and("ldap-key-store", + TEST_LDAP_KEY_STORE_NAME); + private static final Address TEST_LDAP_KEY_STORE_ADDRESS2 = SUBSYSTEM_ADDRESS .and("ldap-key-store", + TEST_LDAP_KEY_STORE_NAME2); + + private static final String TEST_SEARCH_PATH = "CN=Users"; + + private final AddDirContext addDirContext = new AddDirContext.Builder(TEST_DIR_CONTEXT_NAME) + .url("ldap://localhost") + .principal("CN=user") + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText("password") + .build()) + .authenticationLevel(AddDirContext.AuthenticationLevel.SIMPLE) + .build(); + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_LDAP_KEY_STORE_ADDRESS); + ops.removeIfExists(TEST_LDAP_KEY_STORE_ADDRESS2); + ops.removeIfExists(TEST_DIR_CONTEXT_ADDRESS); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleLdapKeyStore() throws Exception { + + client.apply(addDirContext); + + AddLdapKeyStore addLdapKeyStore = new AddLdapKeyStore.Builder(TEST_LDAP_KEY_STORE_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .searchPath(TEST_SEARCH_PATH) + .build(); + + client.apply(addLdapKeyStore); + assertTrue("Ldap key store should be created", ops.exists(TEST_LDAP_KEY_STORE_ADDRESS)); + } + + @Test + public void addTwoSimpleLdapKeyStores() throws Exception { + client.apply(addDirContext); + + AddLdapKeyStore addLdapKeyStore = new AddLdapKeyStore.Builder(TEST_LDAP_KEY_STORE_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .searchPath(TEST_SEARCH_PATH) + .build(); + + AddLdapKeyStore addLdapKeyStore2 = new AddLdapKeyStore.Builder(TEST_LDAP_KEY_STORE_NAME2) + .dirContext(TEST_DIR_CONTEXT_NAME) + .searchPath(TEST_SEARCH_PATH) + .build(); + + client.apply(addLdapKeyStore); + client.apply(addLdapKeyStore2); + + assertTrue("Ldap key store should be created", ops.exists(TEST_LDAP_KEY_STORE_ADDRESS)); + assertTrue("Second ldap key store should be created", ops.exists(TEST_LDAP_KEY_STORE_ADDRESS2)); + } + + @Test + public void addFullLdapKeyStore() throws Exception { + + client.apply(addDirContext); + + AddLdapKeyStore addLdapKeyStore = new AddLdapKeyStore.Builder(TEST_LDAP_KEY_STORE_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .searchPath(TEST_SEARCH_PATH) + .filterAlias("filter-alias1") + .filterCertificate("filter-certificate1") + .filterIterate("filter-iterate1") + .searchRecursive(true) + .searchTimeLimit(1) + .aliasAttribute("aliasAttribute1") + .certificateAttribute("certificateAttribute1") + .certificateChainAttribute("certificateChainAttribute1") + .certificateChainEncoding("certificateChainEncoding1") + .certificateType("certificateType1") + .keyAttribute("someKeystoreAttribute") + .keyType("someKeyType") + .newItemTemplate(new NewItemTemplateBuilder() + .newItemPath("CN=user") + .newItemRdn("DN=Users") + .addNewItemAttributes( + new NewItemAttributeBuilder() + .name("name1") + .addValues("value 1", "value2") + .build(), + new NewItemAttributeBuilder() + .name("name2") + .addValues("value3", "value4") + .build()) + .build()) + .build(); + + client.apply(addLdapKeyStore); + + assertTrue("Ldap key store should be created", ops.exists(TEST_LDAP_KEY_STORE_ADDRESS)); + + checkAttribute("dir-context", TEST_DIR_CONTEXT_NAME); + checkAttribute("search-path", TEST_SEARCH_PATH); + checkAttribute("filter-alias", "filter-alias1"); + checkAttribute("filter-certificate", "filter-certificate1"); + checkAttribute("filter-iterate", "filter-iterate1"); + checkAttribute("search-recursive", "true"); + checkAttribute("search-time-limit", "1"); + checkAttribute("alias-attribute", "aliasAttribute1"); + checkAttribute("certificate-attribute", "certificateAttribute1"); + checkAttribute("certificate-chain-attribute", "certificateChainAttribute1"); + checkAttribute("certificate-chain-encoding", "certificateChainEncoding1"); + checkAttribute("certificate-type", "certificateType1"); + checkAttribute("key-attribute", "someKeystoreAttribute"); + checkAttribute("key-type", "someKeyType"); + checkAttribute("new-item-template.new-item-path", "CN=user"); + checkAttribute("new-item-template.new-item-rdn", "DN=Users"); + checkAttribute("new-item-template.new-item-attributes[0].name", "name1"); + checkAttribute("new-item-template.new-item-attributes[0].value[0]", "value 1"); + checkAttribute("new-item-template.new-item-attributes[0].value[1]", "value2"); + checkAttribute("new-item-template.new-item-attributes[1].name", "name2"); + checkAttribute("new-item-template.new-item-attributes[1].value[0]", "value3"); + checkAttribute("new-item-template.new-item-attributes[1].value[1]", "value4"); + } + + @Test(expected = CommandFailedException.class) + public void addDuplicateLdapKeyStoreNotAllowed() throws Exception { + client.apply(addDirContext); + + AddLdapKeyStore addLdapKeyStore = new AddLdapKeyStore.Builder(TEST_LDAP_KEY_STORE_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .searchPath(TEST_SEARCH_PATH) + .build(); + + AddLdapKeyStore addLdapKeyStore2 = new AddLdapKeyStore.Builder(TEST_LDAP_KEY_STORE_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .searchPath(TEST_SEARCH_PATH) + .build(); + + client.apply(addLdapKeyStore); + assertTrue("Ldap key store should be created", ops.exists(TEST_LDAP_KEY_STORE_ADDRESS)); + client.apply(addLdapKeyStore2); + fail("Ldap key store " + TEST_LDAP_KEY_STORE_NAME + "already exists in configuration, exception should be thrown"); + } + + @Test + public void addDuplicateLdapKeyStoreAllowed() throws Exception { + client.apply(addDirContext); + + AddLdapKeyStore addLdapKeyStore = new AddLdapKeyStore.Builder(TEST_LDAP_KEY_STORE_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .searchPath(TEST_SEARCH_PATH) + .searchTimeLimit(1000) + .build(); + + AddLdapKeyStore addLdapKeyStore2 = new AddLdapKeyStore.Builder(TEST_LDAP_KEY_STORE_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .searchPath(TEST_SEARCH_PATH) + .searchTimeLimit(2000) + .replaceExisting() + .build(); + + client.apply(addLdapKeyStore); + assertTrue("Ldap realm should be created", ops.exists(TEST_LDAP_KEY_STORE_ADDRESS)); + client.apply(addLdapKeyStore2); + assertTrue("Ldap realm should be created", ops.exists(TEST_LDAP_KEY_STORE_ADDRESS)); + // check whether it was really rewritten + checkAttribute("search-time-limit", "2000"); + + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapKeyStore_nullName() throws Exception { + new AddLdapKeyStore.Builder(null) + .dirContext(TEST_DIR_CONTEXT_NAME) + .searchPath(TEST_SEARCH_PATH) + .build(); + fail("Creating command with null ldap keystore name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapKeyStore_emptyName() throws Exception { + new AddLdapKeyStore.Builder("") + .dirContext(TEST_DIR_CONTEXT_NAME) + .searchPath(TEST_SEARCH_PATH) + .build(); + fail("Creating command with empty ldap keystore name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapKeyStore_nullDirContext() throws Exception { + new AddLdapKeyStore.Builder(TEST_LDAP_KEY_STORE_NAME) + .dirContext(null) + .searchPath(TEST_SEARCH_PATH) + .build(); + fail("Creating command with null ldap keystore name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapKeyStore_emptyDirContext() throws Exception { + new AddLdapKeyStore.Builder(TEST_LDAP_KEY_STORE_NAME) + .dirContext("") + .searchPath(TEST_SEARCH_PATH) + .build(); + fail("Creating command with empty ldap keystore name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapKeyStore_nullSearchPath() throws Exception { + new AddLdapKeyStore.Builder(TEST_LDAP_KEY_STORE_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .searchPath(null) + .build(); + fail("Creating command with null ldap keystore search path should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapKeyStore_emptySearchPath() throws Exception { + new AddLdapKeyStore.Builder(TEST_LDAP_KEY_STORE_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .searchPath("") + .build(); + fail("Creating command with empty ldap keystore search path should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapKeyStore_nullNewItemPath_newItemTemplate() throws Exception { + new AddLdapKeyStore.Builder(TEST_LDAP_KEY_STORE_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .searchPath(TEST_SEARCH_PATH) + .newItemTemplate(new NewItemTemplateBuilder() + .newItemPath(null) + .newItemRdn("DN=Users") + .build()) + .build(); + fail("Creating command with null ldap keystore new-item-template.new-item-path should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapKeyStore_emptyNewItemPath_newItemTemplate() throws Exception { + new AddLdapKeyStore.Builder(TEST_LDAP_KEY_STORE_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .searchPath(TEST_SEARCH_PATH) + .newItemTemplate(new NewItemTemplateBuilder() + .newItemPath("") + .newItemRdn("DN=Users") + .build()) + .build(); + fail("Creating command with empty ldap keystore new-item-template.new-item-path should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapKeyStore_nullNewItemRdn_newItemTemplate() throws Exception { + new AddLdapKeyStore.Builder(TEST_LDAP_KEY_STORE_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .searchPath(TEST_SEARCH_PATH) + .newItemTemplate(new NewItemTemplateBuilder() + .newItemPath("CN=user") + .newItemRdn(null) + .build()) + .build(); + fail("Creating command with null ldap keystore new-item-template.new-item-rdn should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addLdapKeyStore_emptyNewItemRdn_newItemTemplate() throws Exception { + new AddLdapKeyStore.Builder(TEST_LDAP_KEY_STORE_NAME) + .dirContext(TEST_DIR_CONTEXT_NAME) + .searchPath(TEST_SEARCH_PATH) + .newItemTemplate(new NewItemTemplateBuilder() + .newItemPath("CN=user") + .newItemRdn("") + .build()) + .build(); + fail("Creating command with empty ldap keystore new-item-template.new-item-rdn should throw exception"); + } + + private void checkAttribute(String attribute, String expectedValue) throws IOException { + checkAttribute(TEST_LDAP_KEY_STORE_ADDRESS, attribute, expectedValue); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddServerSSLContextOfflineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddServerSSLContextOfflineTest.java new file mode 100644 index 00000000..5bdd6102 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddServerSSLContextOfflineTest.java @@ -0,0 +1,279 @@ +package org.wildfly.extras.creaper.commands.elytron.tls; + +import static org.junit.Assert.fail; +import static org.wildfly.extras.creaper.XmlAssert.assertXmlIdentical; + +import com.google.common.base.Charsets; +import com.google.common.io.Files; +import java.io.File; +import org.custommonkey.xmlunit.XMLUnit; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.ManagementClient; +import org.wildfly.extras.creaper.core.offline.OfflineManagementClient; +import org.wildfly.extras.creaper.core.offline.OfflineOptions; + +public class AddServerSSLContextOfflineTest { + + private static final String SUBSYSTEM_EMPTY = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_TLS_EMPTY = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_SERVER_SSL_CONTEXTS_EMPTY = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_SIMPLE = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_EXPECTED_REPLACE = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_SECOND_SERVER_SSL_CONTEXT = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_FULL = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + @Rule + public final TemporaryFolder tmp = new TemporaryFolder(); + + @Before + public void setUp() { + XMLUnit.setNormalizeWhitespace(true); + } + + @Test + public void addSimpleToEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddServerSSLContext addServerSslContext = new AddServerSSLContext.Builder("serverSslContext") + .keyManager("keyManager") + .build(); + + assertXmlIdentical(SUBSYSTEM_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addServerSslContext); + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addSimpleToTlsEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_TLS_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddServerSSLContext addServerSslContext = new AddServerSSLContext.Builder("serverSslContext") + .keyManager("keyManager") + .build(); + + assertXmlIdentical(SUBSYSTEM_TLS_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addServerSslContext); + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addSimpleToServerSslContextsEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SERVER_SSL_CONTEXTS_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddServerSSLContext addServerSslContext = new AddServerSSLContext.Builder("serverSslContext") + .keyManager("keyManager") + .build(); + + assertXmlIdentical(SUBSYSTEM_SERVER_SSL_CONTEXTS_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addServerSslContext); + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test(expected = CommandFailedException.class) + public void existing() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddServerSSLContext addServerSslContext = new AddServerSSLContext.Builder("serverSslContext") + .keyManager("keyManager") + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addServerSslContext); + + fail("Server SSL context serverSslContext already exists in configuration, exception should be thrown"); + } + + @Test + public void overrideExisting() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddServerSSLContext addServerSslContext = new AddServerSSLContext.Builder("serverSslContext") + .keyManager("keyManager") + .cipherSuiteFilter("ALL") + .replaceExisting() + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addServerSslContext); + assertXmlIdentical(SUBSYSTEM_EXPECTED_REPLACE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void overrideNonExisting() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddServerSSLContext addServerSslContext = new AddServerSSLContext.Builder("serverSslContext2") + .keyManager("keyManager") + .replaceExisting() + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addServerSslContext); + assertXmlIdentical(SUBSYSTEM_SECOND_SERVER_SSL_CONTEXT, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addSecondServerSslContext() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddServerSSLContext addServerSslContext = new AddServerSSLContext.Builder("serverSslContext2") + .keyManager("keyManager") + .replaceExisting() + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addServerSslContext); + assertXmlIdentical(SUBSYSTEM_SECOND_SERVER_SSL_CONTEXT, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addFullToEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddServerSSLContext addServerSslContext = new AddServerSSLContext.Builder("serverSslContext") + .cipherSuiteFilter("ALL") + .maximumSessionCacheSize(40) + .sessionTimeout(30) + .keyManager("keyManager") + .trustManager("trustManager") + .protocols("TLSv1.2", "TLSv1.1") + .authenticationOptional(true) + .needClientAuth(false) + .wantClientAuth(true) + .securityDomain("securityDomain") + .realmMapper("realmMapper") + .preRealmPrincipalTransformer("preRealmPrincipalTransformer") + .postRealmPrincipalTransformer("postRealmPrincipalTransformer") + .finalPrincipalTransformer("finalPrincipalTransformer") + .providerName("ksProvider") + .providers("ksProviderLoader") + .useCipherSuitesOrder(false) + .wrap(true) + .build(); + + assertXmlIdentical(SUBSYSTEM_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addServerSslContext); + assertXmlIdentical(SUBSYSTEM_FULL, Files.toString(cfg, Charsets.UTF_8)); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddServerSSLContextOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddServerSSLContextOnlineTest.java new file mode 100644 index 00000000..be2c1dbd --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddServerSSLContextOnlineTest.java @@ -0,0 +1,246 @@ +package org.wildfly.extras.creaper.commands.elytron.tls; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.mapper.AddConstantPrincipalTransformer; +import org.wildfly.extras.creaper.commands.elytron.mapper.AddConstantRealmMapper; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.OnlineManagementClient; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +@RunWith(Arquillian.class) +public class AddServerSSLContextOnlineTest extends AbstractAddSSLContextOnlineTest { + + private static final String SERVER_SSL_CONTEXT_PROTOCOL = "TLSv1.2"; + private static final String SERVER_SSL_CONTEXT_NAME = "CreaperTestServerSSLContext"; + private static final String SERVER_SSL_CONTEXT_NAME2 = "CreaperTestServerSSLContext2"; + private static final String PRE_REALM_PRINCIPAL_TRANSFORMER = "preRealmPrincipalTransformer"; + private static final String POST_REALM_PRINCIPAL_TRANSFORMER = "postRealmPrincipalTransformer"; + private static final String FINAL_PRINCIPAL_TRANSFORMER = "finalPrincipalTransformer"; + private static final String REALM_MAPPER = "realmMapper"; + private static final Address SERVER_SSL_CONTEXT_ADDRESS = SUBSYSTEM_ADDRESS.and("server-ssl-context", + SERVER_SSL_CONTEXT_NAME); + private static final Address SERVER_SSL_CONTEXT_ADDRESS2 = SUBSYSTEM_ADDRESS.and("server-ssl-context", + SERVER_SSL_CONTEXT_NAME2); + private static final Address REALM_MAPPER_ADDRESS = SUBSYSTEM_ADDRESS.and("constant-realm-mapper", + REALM_MAPPER); + private static final Address PRE_REALM_PRINCIPAL_TRANSFORMER_ADDRESS = SUBSYSTEM_ADDRESS + .and("pre-realm-principal-transformer", PRE_REALM_PRINCIPAL_TRANSFORMER); + private static final Address POST_REALM_PRINCIPAL_TRANSFORMER_ADDRESS = SUBSYSTEM_ADDRESS + .and("constant-principal-transformer", POST_REALM_PRINCIPAL_TRANSFORMER); + private static final Address FINAL_PRINCIPAL_TRANSFORMER_ADDRESS = SUBSYSTEM_ADDRESS + .and("constant-principal-transformer", FINAL_PRINCIPAL_TRANSFORMER); + + @BeforeClass + public static void addServerSslContextDependentResources() throws Exception { + OnlineManagementClient client = null; + try { + client = createManagementClient(); + client.apply(new AddConstantPrincipalTransformer.Builder(PRE_REALM_PRINCIPAL_TRANSFORMER) + .constant(PRE_REALM_PRINCIPAL_TRANSFORMER) + .build()); + + client.apply(new AddConstantPrincipalTransformer.Builder(POST_REALM_PRINCIPAL_TRANSFORMER) + .constant(POST_REALM_PRINCIPAL_TRANSFORMER) + .build()); + + client.apply(new AddConstantPrincipalTransformer.Builder(FINAL_PRINCIPAL_TRANSFORMER) + .constant(FINAL_PRINCIPAL_TRANSFORMER) + .build()); + + client.apply(new AddConstantRealmMapper.Builder(REALM_MAPPER) + .realmName(REALM_MAPPER) + .build()); + } finally { + if (client != null) { + client.close(); + } + } + } + + @AfterClass + public static void removeServerSslDependentResources() throws Exception { + OnlineManagementClient client = null; + try { + client = createManagementClient(); + Operations ops = new Operations(client); + Administration administration = new Administration(client); + ops.removeIfExists(REALM_MAPPER_ADDRESS); + ops.removeIfExists(PRE_REALM_PRINCIPAL_TRANSFORMER_ADDRESS); + ops.removeIfExists(POST_REALM_PRINCIPAL_TRANSFORMER_ADDRESS); + ops.removeIfExists(FINAL_PRINCIPAL_TRANSFORMER_ADDRESS); + administration.reloadIfRequired(); + } finally { + if (client != null) { + client.close(); + } + } + } + + @After + public void cleanup() throws Exception { + ops.removeIfExists(SERVER_SSL_CONTEXT_ADDRESS); + ops.removeIfExists(SERVER_SSL_CONTEXT_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleServerSSLContext() throws Exception { + AddServerSSLContext addServerSSLContext = new AddServerSSLContext.Builder(SERVER_SSL_CONTEXT_NAME) + .keyManager(TEST_KEY_MNGR_NAME) + .build(); + assertFalse("The server ssl context should not exist", ops.exists(SERVER_SSL_CONTEXT_ADDRESS)); + client.apply(addServerSSLContext); + assertTrue("Server ssl context should be created", ops.exists(SERVER_SSL_CONTEXT_ADDRESS)); + } + + @Test + public void addTwoSimpleServerSSLContexts() throws Exception { + AddServerSSLContext addServerSSLContext = new AddServerSSLContext.Builder(SERVER_SSL_CONTEXT_NAME) + .keyManager(TEST_KEY_MNGR_NAME) + .build(); + AddServerSSLContext addServerSSLContext2 = new AddServerSSLContext.Builder(SERVER_SSL_CONTEXT_NAME2) + .keyManager(TEST_KEY_MNGR_NAME) + .build(); + + assertFalse("The server ssl context should not exist", ops.exists(SERVER_SSL_CONTEXT_ADDRESS)); + assertFalse("The server ssl context should not exist", ops.exists(SERVER_SSL_CONTEXT_ADDRESS2)); + + client.apply(addServerSSLContext); + client.apply(addServerSSLContext2); + + assertTrue("Server SSL context should be created", ops.exists(SERVER_SSL_CONTEXT_ADDRESS)); + assertTrue("Server SSL context should be created", ops.exists(SERVER_SSL_CONTEXT_ADDRESS2)); + } + + @Test(expected = CommandFailedException.class) + public void addDuplicateServerSSLContextNotAllowed() throws Exception { + AddServerSSLContext addServerSSLContext = new AddServerSSLContext.Builder(SERVER_SSL_CONTEXT_NAME) + .keyManager(TEST_KEY_MNGR_NAME) + .build(); + AddServerSSLContext addServerSSLContext2 = new AddServerSSLContext.Builder(SERVER_SSL_CONTEXT_NAME) + .keyManager(TEST_KEY_MNGR_NAME) + .build(); + + client.apply(addServerSSLContext); + assertTrue("The server ssl context should be created", ops.exists(SERVER_SSL_CONTEXT_ADDRESS)); + + client.apply(addServerSSLContext2); + fail("Server ssl context is already configured, exception should be thrown"); + } + + @Test + public void addDuplicateKeyManagerAllowed() throws Exception { + AddServerSSLContext addServerSSLContext = new AddServerSSLContext.Builder(SERVER_SSL_CONTEXT_NAME) + .keyManager(TEST_KEY_MNGR_NAME) + .build(); + AddServerSSLContext addServerSSLContext2 = new AddServerSSLContext.Builder(SERVER_SSL_CONTEXT_NAME) + .keyManager(TEST_KEY_MNGR_NAME) + .sessionTimeout(5) + .replaceExisting() + .build(); + + client.apply(addServerSSLContext); + assertTrue("The server ssl context should be created", ops.exists(SERVER_SSL_CONTEXT_ADDRESS)); + + client.apply(addServerSSLContext2); + assertTrue("The server ssl context should be created", ops.exists(SERVER_SSL_CONTEXT_ADDRESS)); + // check whether it was really rewritten + checkAttribute(SERVER_SSL_CONTEXT_ADDRESS, "session-timeout", "5"); + } + + @Test + public void addFullServerSSLContext() throws Exception { + AddServerSSLContext addServerSSLContext = new AddServerSSLContext.Builder(SERVER_SSL_CONTEXT_NAME) + .cipherSuiteFilter("ALL") + .keyManager(TEST_KEY_MNGR_NAME) + .trustManager(TRUST_MNGR_NAME) + .maximumSessionCacheSize(0) + .sessionTimeout(0) + .protocols(SERVER_SSL_CONTEXT_PROTOCOL) + .needClientAuth(true) + .wantClientAuth(true) + .authenticationOptional(true) + .securityDomain("ApplicationDomain") + .realmMapper(REALM_MAPPER) + .preRealmPrincipalTransformer(PRE_REALM_PRINCIPAL_TRANSFORMER) + .postRealmPrincipalTransformer(POST_REALM_PRINCIPAL_TRANSFORMER) + .finalPrincipalTransformer(FINAL_PRINCIPAL_TRANSFORMER) + .useCipherSuitesOrder(false) + .wrap(true) + .build(); + client.apply(addServerSSLContext); + assertTrue("The server ssl context should be created", ops.exists(SERVER_SSL_CONTEXT_ADDRESS)); + + checkAttribute("cipher-suite-filter", "ALL"); + checkAttribute("key-manager", TEST_KEY_MNGR_NAME); + checkAttribute("trust-manager", TRUST_MNGR_NAME); + checkAttribute("maximum-session-cache-size", "0"); + checkAttribute("session-timeout", "0"); + checkAttribute("protocols", Arrays.asList(SERVER_SSL_CONTEXT_PROTOCOL)); + checkAttribute("need-client-auth", "true"); + checkAttribute("want-client-auth", "true"); + checkAttribute("authentication-optional", "true"); + checkAttribute("security-domain", "ApplicationDomain"); + checkAttribute("realm-mapper", REALM_MAPPER); + checkAttribute("pre-realm-principal-transformer", PRE_REALM_PRINCIPAL_TRANSFORMER); + checkAttribute("post-realm-principal-transformer", POST_REALM_PRINCIPAL_TRANSFORMER); + checkAttribute("final-principal-transformer", FINAL_PRINCIPAL_TRANSFORMER); + checkAttribute("use-cipher-suites-order", "false"); + checkAttribute("wrap", "true"); + } + + @Test(expected = IllegalArgumentException.class) + public void addServerSSLContext_nullName() throws Exception { + new AddServerSSLContext.Builder(null) + .keyManager(TEST_KEY_MNGR_NAME) + .build(); + fail("Creating command with null server SSL context name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addServerSSLContext_emptyName() throws Exception { + new AddServerSSLContext.Builder("") + .keyManager(TEST_KEY_MNGR_NAME) + .build(); + fail("Creating command with empty server ssl context name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addKeyManager_nullKeyManager() throws Exception { + new AddServerSSLContext.Builder(SERVER_SSL_CONTEXT_NAME) + .keyManager(null) + .build(); + fail("Creating command with null key manager should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addKeyManager_emptyAlgorithm() throws Exception { + new AddServerSSLContext.Builder(SERVER_SSL_CONTEXT_NAME) + .keyManager("") + .build(); + fail("Creating command with empty key manager should throw exception"); + } + + private void checkAttribute(String attribute, String expectedValue) throws IOException { + checkAttribute(SERVER_SSL_CONTEXT_ADDRESS, attribute, expectedValue); + } + + private void checkAttribute(String attribute, List expected) throws IOException { + checkAttribute(SERVER_SSL_CONTEXT_ADDRESS, attribute, expected); + } + +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddTrustManagerOfflineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddTrustManagerOfflineTest.java new file mode 100644 index 00000000..5b9b40fb --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddTrustManagerOfflineTest.java @@ -0,0 +1,266 @@ +package org.wildfly.extras.creaper.commands.elytron.tls; + +import static org.junit.Assert.fail; +import static org.wildfly.extras.creaper.XmlAssert.assertXmlIdentical; + +import java.io.File; + +import org.custommonkey.xmlunit.XMLUnit; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.wildfly.extras.creaper.commands.elytron.tls.AddTrustManager.CertificateRevocationListBuilder; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.ManagementClient; +import org.wildfly.extras.creaper.core.offline.OfflineManagementClient; +import org.wildfly.extras.creaper.core.offline.OfflineOptions; + +import com.google.common.base.Charsets; +import com.google.common.io.Files; + +public class AddTrustManagerOfflineTest { + + private static final String SUBSYSTEM_EMPTY = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_TLS_EMPTY = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_TRUST_MANAGERS_EMPTY = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_SIMPLE = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_EXPECTED_REPLACE = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_SECOND_TRUST_MANAGER = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_FULL = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + @Rule + public final TemporaryFolder tmp = new TemporaryFolder(); + + @Before + public void setUp() { + XMLUnit.setNormalizeWhitespace(true); + } + + @Test + public void addSimpleToEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddTrustManager addTrustManager = new AddTrustManager.Builder("creaperTrustManager") + .algorithm("SunX509") + .build(); + + assertXmlIdentical(SUBSYSTEM_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addTrustManager); + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addSimpleToTlsEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_TLS_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddTrustManager addTrustManager = new AddTrustManager.Builder("creaperTrustManager") + .algorithm("SunX509") + .build(); + + assertXmlIdentical(SUBSYSTEM_TLS_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addTrustManager); + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addSimpleToTrustManagerEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_TRUST_MANAGERS_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddTrustManager addTrustManager = new AddTrustManager.Builder("creaperTrustManager") + .algorithm("SunX509") + .build(); + + assertXmlIdentical(SUBSYSTEM_TRUST_MANAGERS_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addTrustManager); + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test(expected = CommandFailedException.class) + public void existing() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddTrustManager addTrustManager = new AddTrustManager.Builder("creaperTrustManager") + .algorithm("SunX509") + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addTrustManager); + + fail("Trust manager creaperTrustManager already exists in configuration, exception should be thrown"); + } + + @Test + public void overrideExisting() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddTrustManager addTrustManager = new AddTrustManager.Builder("creaperTrustManager") + .algorithm("SunX509-2") + .replaceExisting() + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addTrustManager); + assertXmlIdentical(SUBSYSTEM_EXPECTED_REPLACE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void overrideNonExisting() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddTrustManager addTrustManager = new AddTrustManager.Builder("creaperTrustManager2") + .algorithm("SunX509") + .replaceExisting() + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addTrustManager); + assertXmlIdentical(SUBSYSTEM_SECOND_TRUST_MANAGER, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addSecondTrustManager() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddTrustManager addTrustManager = new AddTrustManager.Builder("creaperTrustManager2") + .algorithm("SunX509") + .replaceExisting() + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addTrustManager); + assertXmlIdentical(SUBSYSTEM_SECOND_TRUST_MANAGER, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addFullToEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddTrustManager addTrustManager = new AddTrustManager.Builder("creaperTrustManager") + .algorithm("SunX509") + .aliasFilter("aliasInFilter") + .keyStore("creaperKeyStore") + .providerName("ksProvider") + .providers("ksProviderLoader") + .certificateRevocationList(new CertificateRevocationListBuilder() + .path("path") + .relativeTo("relativeTo") + .maximumCertPath(3) + .build()) + .build(); + + assertXmlIdentical(SUBSYSTEM_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addTrustManager); + assertXmlIdentical(SUBSYSTEM_FULL, Files.toString(cfg, Charsets.UTF_8)); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddTrustManagerOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddTrustManagerOnlineTest.java new file mode 100644 index 00000000..064435bb --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/elytron/tls/AddTrustManagerOnlineTest.java @@ -0,0 +1,185 @@ +package org.wildfly.extras.creaper.commands.elytron.tls; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; + +import javax.net.ssl.TrustManagerFactory; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.commands.elytron.CredentialRef; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.OnlineManagementClient; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +@RunWith(Arquillian.class) +public class AddTrustManagerOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_KEY_STORE_NAME = "CreaperTestKeyStore"; + private static final String TEST_KEY_STORE_NAME2 = "CreaperTestKeyStore2"; + private static final Address TEST_KEY_STORE_ADDRESS = SUBSYSTEM_ADDRESS.and("key-store", TEST_KEY_STORE_NAME); + private static final Address TEST_KEY_STORE_ADDRESS2 = SUBSYSTEM_ADDRESS.and("key-store", TEST_KEY_STORE_NAME2); + private static final String TEST_KEY_STORE_TYPE = "JKS"; + private static final String TEST_KEY_STORE_PASSWORD = "password"; + private static final String TRUST_MNGR_NAME = "CreaperTestTrustManager"; + private static final String TRUST_MNGR_NAME2 = "CreaperTestTrustManager2"; + private static final Address TRUST_MNGR_ADDRESS = SUBSYSTEM_ADDRESS.and("trust-manager", TRUST_MNGR_NAME); + private static final Address TRUST_MANAGER_ADDRESS2 = SUBSYSTEM_ADDRESS.and("trust-manager", TRUST_MNGR_NAME2); + private static final String TEST_TRUST_MANAGER_ALGORITHM = TrustManagerFactory.getDefaultAlgorithm(); + + @BeforeClass + public static void addKeyStores() throws Exception { + OnlineManagementClient client = null; + try { + client = createManagementClient(); + AddKeyStore addKeyStore = new AddKeyStore.Builder(TEST_KEY_STORE_NAME) + .type(TEST_KEY_STORE_TYPE) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_STORE_PASSWORD) + .build()) + .build(); + AddKeyStore addKeyStore2 = new AddKeyStore.Builder(TEST_KEY_STORE_NAME2) + .type(TEST_KEY_STORE_TYPE) + .credentialReference(new CredentialRef.CredentialRefBuilder() + .clearText(TEST_KEY_STORE_PASSWORD) + .build()) + .build(); + + client.apply(addKeyStore); + client.apply(addKeyStore2); + } finally { + if (client != null) { + client.close(); + } + } + } + + @AfterClass + public static void removeKeyStores() throws Exception { + OnlineManagementClient client = null; + try { + client = createManagementClient(); + Operations ops = new Operations(client); + Administration administration = new Administration(client); + ops.removeIfExists(TEST_KEY_STORE_ADDRESS); + ops.removeIfExists(TEST_KEY_STORE_ADDRESS2); + administration.reloadIfRequired(); + } finally { + if (client != null) { + client.close(); + } + } + } + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TRUST_MNGR_ADDRESS); + ops.removeIfExists(TRUST_MANAGER_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addSimpleTrustManager() throws Exception { + AddTrustManager addTrustManager = new AddTrustManager.Builder(TRUST_MNGR_NAME) + .keyStore(TEST_KEY_STORE_NAME) + .build(); + assertFalse("The trust manager should not exist", ops.exists(TRUST_MNGR_ADDRESS)); + client.apply(addTrustManager); + assertTrue("Trust manager should be created", ops.exists(TRUST_MNGR_ADDRESS)); + } + + @Test + public void addTwoSimpleTrustManagers() throws Exception { + AddTrustManager addTrustManager = new AddTrustManager.Builder(TRUST_MNGR_NAME) + .keyStore(TEST_KEY_STORE_NAME) + .build(); + AddTrustManager addTrustManager2 = new AddTrustManager.Builder(TRUST_MNGR_NAME2) + .keyStore(TEST_KEY_STORE_NAME2) + .build(); + + assertFalse("The trust manager should not exist", ops.exists(TRUST_MNGR_ADDRESS)); + assertFalse("The trust manager should not exist", ops.exists(TRUST_MANAGER_ADDRESS2)); + + client.apply(addTrustManager); + client.apply(addTrustManager2); + + assertTrue("Trust manager should be created", ops.exists(TRUST_MNGR_ADDRESS)); + assertTrue("Trust manager should be created", ops.exists(TRUST_MANAGER_ADDRESS2)); + } + + @Test(expected = CommandFailedException.class) + public void addDuplicateTrustManagersNotAllowed() throws Exception { + AddTrustManager addTrustManager = new AddTrustManager.Builder(TRUST_MNGR_NAME) + .keyStore(TEST_KEY_STORE_NAME) + .build(); + AddTrustManager addTrustManager2 = new AddTrustManager.Builder(TRUST_MNGR_NAME) + .keyStore(TEST_KEY_STORE_NAME) + .build(); + + client.apply(addTrustManager); + assertTrue("The trust manager should be created", ops.exists(TRUST_MNGR_ADDRESS)); + + client.apply(addTrustManager2); + fail("Trust manager is already configured, exception should be thrown"); + } + + @Test + public void addDuplicateTrustManagerAllowed() throws Exception { + AddTrustManager addTrustManager = new AddTrustManager.Builder(TRUST_MNGR_NAME) + .keyStore(TEST_KEY_STORE_NAME) + .build(); + AddTrustManager addTrustManager2 = new AddTrustManager.Builder(TRUST_MNGR_NAME) + .keyStore(TEST_KEY_STORE_NAME) + .replaceExisting() + .build(); + + client.apply(addTrustManager); + assertTrue("The trust manager should be created", ops.exists(TRUST_MNGR_ADDRESS)); + + client.apply(addTrustManager2); + assertTrue("The trust manager should be created", ops.exists(TRUST_MNGR_ADDRESS)); + } + + @Test + public void addFullTrustManager() throws Exception { + AddTrustManager addTrustManager = new AddTrustManager.Builder(TRUST_MNGR_NAME) + .algorithm(TEST_TRUST_MANAGER_ALGORITHM) + .aliasFilter("server-alias") + .keyStore(TEST_KEY_STORE_NAME) + .build(); + client.apply(addTrustManager); + assertTrue("Trust manager should be created", ops.exists(TRUST_MNGR_ADDRESS)); + + checkAttribute("algorithm", TEST_TRUST_MANAGER_ALGORITHM); + checkAttribute("alias-filter", "server-alias"); + checkAttribute("key-store", TEST_KEY_STORE_NAME); + } + + @Test(expected = IllegalArgumentException.class) + public void addTrustManager_nullName() throws Exception { + new AddTrustManager.Builder(null) + .build(); + fail("Creating command with null trust manager name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addTrustManager_emptyName() throws Exception { + new AddTrustManager.Builder("") + .build(); + fail("Creating command with empty trust manager name should throw exception"); + } + + private void checkAttribute(String attribute, String expectedValue) throws IOException { + checkAttribute(TRUST_MNGR_ADDRESS, attribute, expectedValue); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/undertow/AddApplicationSecurityDomainOfflineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/undertow/AddApplicationSecurityDomainOfflineTest.java new file mode 100644 index 00000000..02646eb2 --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/undertow/AddApplicationSecurityDomainOfflineTest.java @@ -0,0 +1,240 @@ +package org.wildfly.extras.creaper.commands.undertow; + +import static org.junit.Assert.fail; +import static org.wildfly.extras.creaper.XmlAssert.assertXmlIdentical; +import com.google.common.base.Charsets; +import com.google.common.io.Files; +import java.io.File; +import org.custommonkey.xmlunit.XMLUnit; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.ManagementClient; +import org.wildfly.extras.creaper.core.offline.OfflineManagementClient; +import org.wildfly.extras.creaper.core.offline.OfflineOptions; + +public class AddApplicationSecurityDomainOfflineTest { + + private static final String SUBSYSTEM_EMPTY = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_DOMAINS_EMPTY = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_SIMPLE = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_EXPECTED_REPLACE = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_SECOND_DOMAIN = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String SUBSYSTEM_FULL = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + @Rule + public final TemporaryFolder tmp = new TemporaryFolder(); + + @Before + public void setUp() { + XMLUnit.setNormalizeWhitespace(true); + } + + @Test + public void addSimpleToEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddApplicationSecurityDomain addApplicationSecurityDomain = new AddApplicationSecurityDomain + .Builder("appSecDomain") + .httpAuthenticationFactory("httpAuthFactory") + .build(); + + assertXmlIdentical(SUBSYSTEM_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addApplicationSecurityDomain); + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addSimpleToAppSecDomainsEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_DOMAINS_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddApplicationSecurityDomain addApplicationSecurityDomain = new AddApplicationSecurityDomain + .Builder("appSecDomain") + .httpAuthenticationFactory("httpAuthFactory") + .build(); + + assertXmlIdentical(SUBSYSTEM_DOMAINS_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addApplicationSecurityDomain); + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test(expected = CommandFailedException.class) + public void existing() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddApplicationSecurityDomain addApplicationSecurityDomain = new AddApplicationSecurityDomain + .Builder("appSecDomain") + .httpAuthenticationFactory("httpAuthFactory") + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addApplicationSecurityDomain); + + fail("Application security domain appSecDomain already exists in configuration, exception should be thrown"); + } + + @Test + public void overrideExisting() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddApplicationSecurityDomain addApplicationSecurityDomain = new AddApplicationSecurityDomain + .Builder("appSecDomain") + .httpAuthenticationFactory("httpAuthFactory2") + .replaceExisting() + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addApplicationSecurityDomain); + assertXmlIdentical(SUBSYSTEM_EXPECTED_REPLACE, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void overrideNonExisting() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddApplicationSecurityDomain addApplicationSecurityDomain = new AddApplicationSecurityDomain + .Builder("appSecDomain2") + .httpAuthenticationFactory("httpAuthFactory") + .replaceExisting() + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addApplicationSecurityDomain); + assertXmlIdentical(SUBSYSTEM_SECOND_DOMAIN, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addSecondKeyStore() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_SIMPLE, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddApplicationSecurityDomain addApplicationSecurityDomain = new AddApplicationSecurityDomain + .Builder("appSecDomain2") + .httpAuthenticationFactory("httpAuthFactory") + .build(); + + assertXmlIdentical(SUBSYSTEM_SIMPLE, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addApplicationSecurityDomain); + assertXmlIdentical(SUBSYSTEM_SECOND_DOMAIN, Files.toString(cfg, Charsets.UTF_8)); + } + + @Test + public void addFullToEmpty() throws Exception { + File cfg = tmp.newFile("xmlTransform.xml"); + Files.write(SUBSYSTEM_EMPTY, cfg, Charsets.UTF_8); + + OfflineManagementClient client = ManagementClient.offline( + OfflineOptions.standalone().configurationFile(cfg).build()); + + AddApplicationSecurityDomain addApplicationSecurityDomain = new AddApplicationSecurityDomain + .Builder("appSecDomain") + .httpAuthenticationFactory("httpAuthFactory") + .overrideDeploymentConfig(true) + .build(); + + assertXmlIdentical(SUBSYSTEM_EMPTY, Files.toString(cfg, Charsets.UTF_8)); + client.apply(addApplicationSecurityDomain); + assertXmlIdentical(SUBSYSTEM_FULL, Files.toString(cfg, Charsets.UTF_8)); + } +} diff --git a/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/undertow/AddApplicationSecurityDomainOnlineTest.java b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/undertow/AddApplicationSecurityDomainOnlineTest.java new file mode 100644 index 00000000..f996008e --- /dev/null +++ b/testsuite/standalone/src/test/java/org/wildfly/extras/creaper/commands/undertow/AddApplicationSecurityDomainOnlineTest.java @@ -0,0 +1,216 @@ +package org.wildfly.extras.creaper.commands.undertow; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; + +import org.jboss.arquillian.junit.Arquillian; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wildfly.extras.creaper.commands.elytron.AbstractElytronOnlineTest; +import org.wildfly.extras.creaper.commands.elytron.domain.AddSecurityDomain; +import org.wildfly.extras.creaper.commands.elytron.http.AddHttpAuthenticationFactory; +import org.wildfly.extras.creaper.commands.elytron.realm.AddIdentityRealm; +import org.wildfly.extras.creaper.core.CommandFailedException; +import org.wildfly.extras.creaper.core.online.ModelNodeResult; +import org.wildfly.extras.creaper.core.online.OnlineManagementClient; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +@RunWith(Arquillian.class) +public class AddApplicationSecurityDomainOnlineTest extends AbstractElytronOnlineTest { + + private static final String TEST_APP_SEC_DOMAIN_NAME = "testAppSecDomain"; + private static final String TEST_APP_SEC_DOMAIN_NAME2 = "testAppSecDomain2"; + private static final String TEST_HTTP_AUTH_FACTORY = "httpAuthFactory"; + private static final String IDENTITY_REALM_NAME = "identityRealm"; + private static final String SECURITY_DOMAIN_NAME = "securityDomain"; + private static final String PROVIDER_HTTP_SERVER_MECH_FACTORY = "global"; + private static final Address TEST_APP_SEC_DOMAIN_ADDRESS = Address.subsystem("undertow") + .and("application-security-domain", TEST_APP_SEC_DOMAIN_NAME); + private static final Address TEST_APP_SEC_DOMAIN_ADDRESS2 = Address.subsystem("undertow") + .and("application-security-domain", TEST_APP_SEC_DOMAIN_NAME2); + + @BeforeClass + public static void addRequiredCapabilities() throws Exception { + OnlineManagementClient client = null; + try { + client = createManagementClient(); + client.apply(new AddIdentityRealm.Builder(IDENTITY_REALM_NAME) + .identity("identity") + .build()); + + client.apply(new AddSecurityDomain.Builder(SECURITY_DOMAIN_NAME) + .defaultRealm(IDENTITY_REALM_NAME) + .realms(new AddSecurityDomain.RealmBuilder(IDENTITY_REALM_NAME).build()) + .build()); + + client.apply(new AddHttpAuthenticationFactory.Builder(TEST_HTTP_AUTH_FACTORY) + .securityDomain(SECURITY_DOMAIN_NAME) + .httpServerMechanismFactory(PROVIDER_HTTP_SERVER_MECH_FACTORY) + .build()); + } finally { + if (client != null) { + client.close(); + } + } + } + + @AfterClass + public static void removeAddedCapabilities() throws Exception { + OnlineManagementClient client = null; + try { + client = createManagementClient(); + Operations ops = new Operations(client); + Administration administration = new Administration(client); + ops.removeIfExists(SUBSYSTEM_ADDRESS.and("http-authentication-factory", TEST_HTTP_AUTH_FACTORY)); + ops.removeIfExists(SUBSYSTEM_ADDRESS.and("security-domain", SECURITY_DOMAIN_NAME)); + ops.removeIfExists(SUBSYSTEM_ADDRESS.and("identity-realm", IDENTITY_REALM_NAME)); + administration.reloadIfRequired(); + } finally { + if (client != null) { + client.close(); + } + } + } + + @After + public void cleanup() throws Exception { + ops.removeIfExists(TEST_APP_SEC_DOMAIN_ADDRESS); + ops.removeIfExists(TEST_APP_SEC_DOMAIN_ADDRESS2); + administration.reloadIfRequired(); + } + + @Test + public void addAppSecDomain() throws Exception { + AddApplicationSecurityDomain addAppSecDomain = new AddApplicationSecurityDomain + .Builder(TEST_APP_SEC_DOMAIN_NAME) + .httpAuthenticationFactory(TEST_HTTP_AUTH_FACTORY) + .build(); + + assertFalse("The application security domain should not exist", ops.exists(TEST_APP_SEC_DOMAIN_ADDRESS)); + client.apply(addAppSecDomain); + assertTrue("Application security domain should be created", ops.exists(TEST_APP_SEC_DOMAIN_ADDRESS)); + } + + @Test + public void addTwoSimpleAppSecDomains() throws Exception { + AddApplicationSecurityDomain addAppSecDomain = new AddApplicationSecurityDomain + .Builder(TEST_APP_SEC_DOMAIN_NAME) + .httpAuthenticationFactory(TEST_HTTP_AUTH_FACTORY) + .build(); + AddApplicationSecurityDomain addAppSecDomain2 = new AddApplicationSecurityDomain + .Builder(TEST_APP_SEC_DOMAIN_NAME2) + .httpAuthenticationFactory(TEST_HTTP_AUTH_FACTORY) + .build(); + + assertFalse("The application security domain should not exist", ops.exists(TEST_APP_SEC_DOMAIN_ADDRESS)); + assertFalse("The application security domain should not exist", ops.exists(TEST_APP_SEC_DOMAIN_ADDRESS2)); + + client.apply(addAppSecDomain); + client.apply(addAppSecDomain2); + + assertTrue("Application security domain should be created", ops.exists(TEST_APP_SEC_DOMAIN_ADDRESS)); + assertTrue("Application security domain should be created", ops.exists(TEST_APP_SEC_DOMAIN_ADDRESS2)); + } + + @Test(expected = CommandFailedException.class) + public void addExistAppSecDomainNotAllowed() throws Exception { + AddApplicationSecurityDomain addAppSecDomain = new AddApplicationSecurityDomain + .Builder(TEST_APP_SEC_DOMAIN_NAME) + .httpAuthenticationFactory(TEST_HTTP_AUTH_FACTORY) + .build(); + AddApplicationSecurityDomain addAppSecDomain2 = new AddApplicationSecurityDomain + .Builder(TEST_APP_SEC_DOMAIN_NAME) + .httpAuthenticationFactory(TEST_HTTP_AUTH_FACTORY) + .build(); + + client.apply(addAppSecDomain); + assertTrue("The application security domain should be created", ops.exists(TEST_APP_SEC_DOMAIN_ADDRESS)); + + client.apply(addAppSecDomain2); + fail("Application security domain is already configured, exception should be thrown"); + } + + @Test + public void addExistAppSecDomainAllowed() throws Exception { + AddApplicationSecurityDomain addAppSecDomain = new AddApplicationSecurityDomain + .Builder(TEST_APP_SEC_DOMAIN_NAME) + .httpAuthenticationFactory(TEST_HTTP_AUTH_FACTORY) + .build(); + AddApplicationSecurityDomain addAppSecDomain2 = new AddApplicationSecurityDomain + .Builder(TEST_APP_SEC_DOMAIN_NAME) + .httpAuthenticationFactory(TEST_HTTP_AUTH_FACTORY) + .overrideDeploymentConfig(true) + .replaceExisting() + .build(); + + client.apply(addAppSecDomain); + assertTrue("The application security domain should be created", ops.exists(TEST_APP_SEC_DOMAIN_ADDRESS)); + + client.apply(addAppSecDomain2); + assertTrue("The application security domain should be created", ops.exists(TEST_APP_SEC_DOMAIN_ADDRESS)); + // check whether it was really rewritten + checkAttribute("override-deployment-config", "true"); + } + + @Test + public void addFullAppSecDomain() throws Exception { + AddApplicationSecurityDomain addAppSecDomain = new AddApplicationSecurityDomain + .Builder(TEST_APP_SEC_DOMAIN_NAME) + .httpAuthenticationFactory(TEST_HTTP_AUTH_FACTORY) + .overrideDeploymentConfig(true) + .build(); + client.apply(addAppSecDomain); + assertTrue("Application security domain should be created", ops.exists(TEST_APP_SEC_DOMAIN_ADDRESS)); + + checkAttribute("http-authentication-factory", TEST_HTTP_AUTH_FACTORY); + checkAttribute("override-deployment-config", "true"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAppSecDomain_nullName() throws Exception { + new AddApplicationSecurityDomain.Builder(null) + .httpAuthenticationFactory(TEST_HTTP_AUTH_FACTORY) + .build(); + fail("Creating command with null name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAppSecDomain_emptyName() throws Exception { + new AddApplicationSecurityDomain.Builder("") + .httpAuthenticationFactory(TEST_HTTP_AUTH_FACTORY) + .build(); + fail("Creating command with empty keystore name should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAppSecDomain_nullHttpAuthFactory() throws Exception { + new AddApplicationSecurityDomain.Builder(TEST_APP_SEC_DOMAIN_NAME) + .httpAuthenticationFactory(null) + .build(); + fail("Creating command with null http authentication factory should throw exception"); + } + + @Test(expected = IllegalArgumentException.class) + public void addAppSecDomain_emptyHttpAuthFactory() throws Exception { + new AddApplicationSecurityDomain.Builder(TEST_APP_SEC_DOMAIN_NAME) + .httpAuthenticationFactory("") + .build(); + fail("Creating command with empty http authentication factory should throw exception"); + } + + private void checkAttribute(String attribute, String expectedValue) throws IOException { + ModelNodeResult readAttribute = ops.readAttribute(TEST_APP_SEC_DOMAIN_ADDRESS, attribute); + readAttribute.assertSuccess("Read operation for " + attribute + " failed"); + assertEquals("Read operation for " + attribute + " return wrong value", expectedValue, + readAttribute.stringValue()); + } +}