keycloak-uncached
Changes
broker/core/pom.xml 2(+1 -1)
broker/oidc/pom.xml 2(+1 -1)
broker/oidc/src/main/java/org/keycloak/broker/oidc/mappers/AbstractJsonUserAttributeMapper.java 206(+206 -0)
broker/oidc/src/test/java/org/keycloak/broker/oidc/mappers/AbstractJsonUserAttributeMapperTest.java 120(+120 -0)
broker/pom.xml 2(+1 -1)
broker/saml/pom.xml 2(+1 -1)
connections/file/pom.xml 2(+1 -1)
connections/http-client/pom.xml 2(+1 -1)
connections/infinispan/pom.xml 2(+1 -1)
connections/jpa/pom.xml 2(+1 -1)
connections/jpa-liquibase/pom.xml 4(+2 -2)
connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate1_2_0_CR1.java 5(+4 -1)
connections/mongo/pom.xml 2(+1 -1)
connections/mongo-update/pom.xml 2(+1 -1)
connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/DefaultMongoUpdaterProvider.java 2(+1 -1)
connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update1_3_0.java 59(+59 -0)
connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update1_3_0_Beta1.java 20(+0 -20)
connections/pom.xml 2(+1 -1)
core/pom.xml 2(+1 -1)
core-jaxrs/pom.xml 2(+1 -1)
dependencies/pom.xml 2(+1 -1)
dependencies/server-all/pom.xml 2(+1 -1)
dependencies/server-min/pom.xml 2(+1 -1)
distribution/adapters/osgi/pom.xml 2(+1 -1)
distribution/adapters/pom.xml 2(+1 -1)
distribution/demo-dist/assembly.xml 21(+20 -1)
distribution/demo-dist/pom.xml 34(+28 -6)
distribution/docs-dist/pom.xml 2(+1 -1)
distribution/examples-dist/pom.xml 2(+1 -1)
distribution/feature-packs/pom.xml 2(+1 -1)
distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/de/idyl/winzipaes/main/module.xml 2(+1 -1)
distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-server-subsystem/main/module.xml 18(+2 -16)
distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-wf9-server-subsystem/main/module.xml 52(+52 -0)
distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/sun/jdk/jgss/main/module.xml 0(+0 -0)
distribution/pom.xml 7(+3 -4)
distribution/proxy-dist/pom.xml 2(+1 -1)
distribution/server-dist/pom.xml 2(+1 -1)
distribution/server-overlay/eap6/eap6-server-modules/pom.xml 313(+158 -155)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/com/google/zxing/core/main/module.xml 26(+13 -13)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/com/google/zxing/javase/main/module.xml 28(+14 -14)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/de/idyl/winzipaes/main/module.xml 26(+13 -13)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/javax/ws/rs/api/2.0/module.xml 12(+12 -0)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/net/iharder/base64/main/module.xml 26(+13 -13)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/bouncycastle/main/module.xml 10(+10 -0)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/freemarker/main/module.xml 28(+14 -14)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-account-api/main/module.xml 36(+18 -18)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-account-freemarker/main/module.xml 48(+24 -24)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-as7-server-subsystem/main/module.xml 2(+1 -1)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-broker-core/main/module.xml 34(+17 -17)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-broker-oidc/main/module.xml 44(+22 -22)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-broker-saml/main/module.xml 38(+19 -19)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-connections-file/main/module.xml 0(+0 -0)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-connections-http-client/main/module.xml 40(+20 -20)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-connections-infinispan/main/module.xml 34(+17 -17)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-connections-jpa/main/module.xml 46(+23 -23)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-connections-jpa-liquibase/main/module.xml 40(+20 -20)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-connections-mongo/main/module.xml 34(+17 -17)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-connections-mongo-update/main/module.xml 0(+0 -0)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-core/main/module.xml 42(+21 -21)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-core-jaxrs/main/module.xml 40(+20 -20)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-email-api/main/module.xml 34(+17 -17)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-email-freemarker/main/module.xml 48(+24 -24)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-events-api/main/module.xml 32(+16 -16)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-events-email/main/module.xml 38(+19 -19)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-events-jboss-logging/main/module.xml 36(+18 -18)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-events-jpa/main/module.xml 48(+24 -24)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-events-mongo/main/module.xml 44(+22 -22)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-export-import-api/main/module.xml 48(+24 -24)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-export-import-dir/main/module.xml 50(+25 -25)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-export-import-single-file/main/module.xml 50(+25 -25)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-export-import-zip/main/module.xml 52(+26 -26)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-forms-common-freemarker/main/module.xml 36(+18 -18)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-forms-common-themes/main/module.xml 38(+19 -19)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-invalidation-cache-infinispan/main/module.xml 38(+19 -19)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-invalidation-cache-model/main/module.xml 40(+20 -20)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-js-adapter/main/module.xml 24(+12 -12)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-kerberos-federation/main/module.xml 0(+0 -0)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-ldap-federation/main/module.xml 38(+19 -19)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-login-api/main/module.xml 36(+18 -18)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-login-freemarker/main/module.xml 52(+26 -26)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-model-api/main/module.xml 34(+17 -17)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-model-file/main/module.xml 0(+0 -0)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-model-jpa/main/module.xml 44(+22 -22)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-model-mongo/main/module.xml 38(+19 -19)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-model-sessions-infinispan/main/module.xml 36(+18 -18)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-model-sessions-jpa/main/module.xml 40(+20 -20)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-model-sessions-mem/main/module.xml 32(+16 -16)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-model-sessions-mongo/main/module.xml 36(+18 -18)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-saml-core/main/module.xml 38(+19 -19)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-saml-protocol/main/module.xml 58(+29 -29)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-server/main/module.xml 122(+61 -61)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-server-subsystem/main/module.xml 39(+39 -0)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-services/main/module.xml 164(+82 -82)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-social-core/main/module.xml 40(+20 -20)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-social-facebook/main/module.xml 44(+22 -22)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-social-github/main/module.xml 44(+22 -22)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-social-google/main/module.xml 44(+22 -22)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-social-linkedin/main/module.xml 44(+22 -22)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-social-stackoverflow/main/module.xml 44(+22 -22)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-social-twitter/main/module.xml 50(+25 -25)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-timer-api/main/module.xml 32(+16 -16)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-timer-basic/main/module.xml 34(+17 -17)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/liquibase/main/module.xml 28(+14 -14)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/mongodb/mongo-java-driver/main/module.xml 26(+13 -13)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/twitter4j/main/module.xml 26(+13 -13)
distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/sun/jdk/jgss/main/module.xml 19(+19 -0)
distribution/server-overlay/eap6/pom.xml 21(+21 -0)
distribution/server-overlay/pom.xml 144(+21 -123)
distribution/src-dist/pom.xml 2(+1 -1)
distribution/subsystem-war/pom.xml 2(+1 -1)
docbook/pom.xml 2(+1 -1)
events/api/pom.xml 2(+1 -1)
events/email/pom.xml 2(+1 -1)
events/jboss-logging/pom.xml 2(+1 -1)
events/jpa/pom.xml 2(+1 -1)
events/mongo/pom.xml 2(+1 -1)
events/pom.xml 2(+1 -1)
events/syslog/pom.xml 2(+1 -1)
examples/admin-client/pom.xml 2(+1 -1)
examples/basic-auth/pom.xml 2(+1 -1)
examples/broker/pom.xml 2(+1 -1)
examples/cors/pom.xml 2(+1 -1)
examples/demo-template/pom.xml 2(+1 -1)
examples/fuse/camel/pom.xml 2(+1 -1)
examples/fuse/cxf-jaxrs/pom.xml 2(+1 -1)
examples/fuse/cxf-jaxws/pom.xml 2(+1 -1)
examples/fuse/features/pom.xml 2(+1 -1)
examples/fuse/pom.xml 2(+1 -1)
examples/js-console/pom.xml 2(+1 -1)
examples/kerberos/pom.xml 2(+1 -1)
examples/multi-tenant/pom.xml 2(+1 -1)
examples/pom.xml 2(+1 -1)
examples/providers/pom.xml 2(+1 -1)
examples/saml/pom.xml 2(+1 -1)
examples/saml/post-basic/pom.xml 17(+9 -8)
examples/saml/redirect-basic/pom.xml 16(+9 -7)
examples/themes/pom.xml 2(+1 -1)
export-import/pom.xml 2(+1 -1)
federation/kerberos/pom.xml 2(+1 -1)
federation/ldap/pom.xml 2(+1 -1)
federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/OrCondition.java 2(+0 -2)
federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPIdentityStore.java 18(+8 -10)
federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPOperationManager.java 20(+10 -10)
federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPFederationProviderFactory.java 4(+2 -2)
federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPIdentityStoreRegistry.java 17(+0 -17)
federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/RoleLDAPFederationMapper.java 7(+2 -5)
federation/pom.xml 2(+1 -1)
forms/account-api/pom.xml 2(+1 -1)
forms/account-freemarker/pom.xml 2(+1 -1)
forms/common-freemarker/pom.xml 2(+1 -1)
forms/common-themes/pom.xml 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/brute-force.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-clustering.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-credentials.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-detail.html 4(+2 -2)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-import.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-installation.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-keys.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-list.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-mappers.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-mappers-add.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-revocation.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-role-detail.html 4(+2 -2)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-role-list.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-saml-key-export.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-saml-key-import.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-saml-keys.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-scope-mappings.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-sessions.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/defense-headers.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/federated-generic.html 4(+2 -2)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/federated-kerberos.html 4(+2 -2)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/federated-ldap.html 4(+2 -2)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/federated-mapper-detail.html 4(+2 -2)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/federated-mappers.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/identity-provider-mapper-detail.html 6(+3 -3)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/identity-provider-mappers.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/protocol-mapper-detail.html 4(+2 -2)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-cache-settings.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-credentials.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-default-roles.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-detail.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events-admin.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events-config.html 4(+2 -2)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-export.html 4(+2 -2)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-oidc.html 4(+2 -2)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-saml.html 4(+2 -2)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-social.html 4(+2 -2)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-stackoverflow-ext.html 14(+7 -7)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-login-settings.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-theme-settings.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-tokens.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/role-detail.html 4(+2 -2)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/role-mappings.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/session-realm.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/session-revocation.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-consents.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-credentials.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-detail.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-federated-identity.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-federation.html 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-sessions.html 2(+1 -1)
forms/email-api/pom.xml 2(+1 -1)
forms/email-freemarker/pom.xml 2(+1 -1)
forms/login-api/pom.xml 2(+1 -1)
forms/login-freemarker/pom.xml 2(+1 -1)
forms/pom.xml 2(+1 -1)
integration/adapter-core/pom.xml 2(+1 -1)
integration/admin-client/pom.xml 10(+4 -6)
integration/admin-client/src/main/java/org/keycloak/admin/client/resource/UsersResource.java 8(+4 -4)
integration/as7-eap6/as7-server-subsystem/pom.xml 104(+104 -0)
integration/as7-eap6/as7-server-subsystem/src/main/java/org/keycloak/subsystem/server/as7/KeycloakAdapterConfigService.java 48(+48 -0)
integration/as7-eap6/as7-server-subsystem/src/main/java/org/keycloak/subsystem/server/as7/KeycloakExtension.java 75(+75 -0)
integration/as7-eap6/as7-server-subsystem/src/main/java/org/keycloak/subsystem/server/as7/KeycloakServerDeploymentProcessor.java 13(+6 -7)
integration/as7-eap6/as7-server-subsystem/src/main/java/org/keycloak/subsystem/server/as7/KeycloakSubsystemAdd.java 86(+86 -0)
integration/as7-eap6/as7-server-subsystem/src/main/java/org/keycloak/subsystem/server/as7/KeycloakSubsystemDefinition.java 72(+14 -58)
integration/as7-eap6/as7-server-subsystem/src/main/java/org/keycloak/subsystem/server/as7/KeycloakSubsystemParser.java 82(+82 -0)
integration/as7-eap6/as7-server-subsystem/src/main/java/org/keycloak/subsystem/server/as7/KeycloakSubsystemRemoveHandler.java 20(+9 -11)
integration/as7-eap6/as7-server-subsystem/src/main/java/org/keycloak/subsystem/server/as7/KeycloakSubsystemWriteAttributeHandler.java 42(+15 -27)
integration/as7-eap6/as7-server-subsystem/src/main/java/org/keycloak/subsystem/server/as7/ServerUtil.java 91(+29 -62)
integration/as7-eap6/as7-server-subsystem/src/main/java/org/keycloak/subsystem/server/logging/KeycloakLogger.java 0(+0 -0)
integration/as7-eap6/as7-server-subsystem/src/main/java/org/keycloak/subsystem/server/logging/KeycloakMessages.java 0(+0 -0)
integration/as7-eap6/as7-server-subsystem/src/main/resources/META-INF/services/org.jboss.as.controller.Extension 1(+1 -0)
integration/as7-eap6/as7-server-subsystem/src/main/resources/org/keycloak/subsystem/server/as7/LocalDescriptions.properties 4(+4 -0)
integration/as7-eap6/as7-server-subsystem/src/main/resources/schema/wildfly-keycloak-server_1_1.xsd 17(+2 -15)
integration/as7-eap6/as7-server-subsystem/src/main/resources/subsystem-templates/keycloak-datasources.xml 0(+0 -0)
integration/as7-eap6/as7-server-subsystem/src/main/resources/subsystem-templates/keycloak-server.xml 5(+1 -4)
integration/as7-eap6/as7-server-subsystem/src/test/resources/org/keycloak/subsystem/server/extension/keycloak-server-1.1.xml 5(+1 -4)
integration/as7-eap6/pom.xml 3(+2 -1)
integration/installed/pom.xml 2(+1 -1)
integration/jetty/jetty8.1/pom.xml 2(+1 -1)
integration/jetty/jetty9.1/pom.xml 2(+1 -1)
integration/jetty/jetty9.2/pom.xml 2(+1 -1)
integration/jetty/jetty-core/pom.xml 2(+1 -1)
integration/jetty/pom.xml 2(+1 -1)
integration/js/pom.xml 2(+1 -1)
integration/osgi-adapter/pom.xml 2(+1 -1)
integration/pom.xml 2(+1 -1)
integration/spring-boot/pom.xml 2(+1 -1)
integration/spring-security/pom.xml 2(+1 -1)
integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandler.java 27(+6 -21)
integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandlerTest.java 96(+96 -0)
integration/tomcat/pom.xml 2(+1 -1)
integration/tomcat/tomcat6/pom.xml 2(+1 -1)
integration/tomcat/tomcat7/pom.xml 2(+1 -1)
integration/tomcat/tomcat8/pom.xml 15(+1 -14)
integration/undertow/pom.xml 2(+1 -1)
integration/wildfly/pom.xml 4(+2 -2)
integration/wildfly/wf9-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakAdapterConfigService.java 36(+9 -27)
integration/wildfly/wf9-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakExtension.java 24(+10 -14)
integration/wildfly/wf9-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakServerDeploymentProcessor.java 46(+24 -22)
integration/wildfly/wf9-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemAdd.java 40(+37 -3)
integration/wildfly/wf9-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemDefinition.java 56(+49 -7)
integration/wildfly/wf9-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemParser.java 69(+12 -57)
integration/wildfly/wf9-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemRemoveHandler.java 65(+65 -0)
integration/wildfly/wf9-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemWriteAttributeHandler.java 71(+71 -0)
integration/wildfly/wf9-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/ServerUtil.java 163(+163 -0)
integration/wildfly/wf9-server-subsystem/src/main/java/org/keycloak/subsystem/server/logging/KeycloakLogger.java 39(+39 -0)
integration/wildfly/wf9-server-subsystem/src/main/java/org/keycloak/subsystem/server/logging/KeycloakMessages.java 34(+34 -0)
integration/wildfly/wf9-server-subsystem/src/main/resources/META-INF/services/org.jboss.as.controller.Extension 0(+0 -0)
integration/wildfly/wf9-server-subsystem/src/main/resources/org/keycloak/subsystem/server/extension/LocalDescriptions.properties 4(+4 -0)
integration/wildfly/wf9-server-subsystem/src/main/resources/schema/wildfly-keycloak-server_1_1.xsd 25(+25 -0)
integration/wildfly/wf9-server-subsystem/src/main/resources/subsystem-templates/keycloak-datasources.xml 22(+22 -0)
integration/wildfly/wf9-server-subsystem/src/main/resources/subsystem-templates/keycloak-server.xml 8(+8 -0)
integration/wildfly/wf9-server-subsystem/src/test/java/org/keycloak/subsystem/server/extension/SubsystemParsingTestCase.java 1(+0 -1)
integration/wildfly/wf9-server-subsystem/src/test/resources/org/keycloak/subsystem/server/extension/keycloak-server-1.1.xml 3(+3 -0)
integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AbstractAddOverlayHandler.java 206(+0 -206)
integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/AuthServerAddHandler.java 74(+0 -74)
integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/ListOverlaysHandler.java 74(+0 -74)
integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/authserver/RemoveOverlayHandler.java 78(+0 -78)
integration/wildfly/wildfly-server-subsystem/src/main/resources/org/keycloak/subsystem/server/extension/LocalDescriptions.properties 26(+0 -26)
model/api/pom.xml 2(+1 -1)
model/file/pom.xml 2(+1 -1)
model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheUserProvider.java 14(+9 -5)
model/invalidation-cache/pom.xml 4(+2 -2)
model/jpa/pom.xml 2(+1 -1)
model/mongo/pom.xml 2(+1 -1)
model/pom.xml 4(+2 -2)
model/sessions-infinispan/pom.xml 2(+1 -1)
model/sessions-infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/LoginFailureEntity.java 6(+6 -0)
model/sessions-infinispan/src/main/java/org/keycloak/models/sessions/infinispan/UsernameLoginFailureAdapter.java 2(+1 -1)
model/sessions-jpa/pom.xml 2(+1 -1)
model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/entities/UsernameLoginFailureEntity.java 7(+7 -0)
model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/UsernameLoginFailureAdapter.java 2(+1 -1)
model/sessions-mem/pom.xml 2(+1 -1)
model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/entities/UsernameLoginFailureEntity.java 7(+7 -0)
model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/UsernameLoginFailureAdapter.java 2(+1 -1)
model/sessions-mongo/pom.xml 2(+1 -1)
model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/UsernameLoginFailureAdapter.java 2(+1 -1)
pom.xml 57(+28 -29)
proxy/launcher/pom.xml 2(+1 -1)
proxy/pom.xml 2(+1 -1)
proxy/proxy-server/pom.xml 2(+1 -1)
saml/pom.xml 2(+1 -1)
saml/saml-core/pom.xml 2(+1 -1)
saml/saml-protocol/pom.xml 2(+1 -1)
services/pom.xml 2(+1 -1)
social/core/pom.xml 2(+1 -1)
social/facebook/pom.xml 2(+1 -1)
social/facebook/src/main/java/org/keycloak/social/facebook/FacebookIdentityProvider.java 95(+49 -46)
social/facebook/src/main/java/org/keycloak/social/facebook/FacebookUserAttributeMapper.java 29(+29 -0)
social/facebook/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper 1(+1 -0)
social/github/pom.xml 2(+1 -1)
social/github/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper 1(+1 -0)
social/google/pom.xml 2(+1 -1)
social/google/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper 1(+1 -0)
social/linkedin/pom.xml 2(+1 -1)
social/linkedin/src/main/java/org/keycloak/social/linkedin/LinkedInUserAttributeMapper.java 29(+29 -0)
social/linkedin/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper 1(+1 -0)
social/pom.xml 2(+1 -1)
social/stackoverflow/pom.xml 2(+1 -1)
social/stackoverflow/src/main/java/org/keycloak/social/stackoverflow/StackoverflowIdentityProvider.java 21(+10 -11)
social/stackoverflow/src/main/java/org/keycloak/social/stackoverflow/StackoverflowUserAttributeMapper.java 29(+29 -0)
social/stackoverflow/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper 1(+1 -0)
social/twitter/pom.xml 2(+1 -1)
testsuite/docker-cluster/pom.xml 6(+3 -3)
testsuite/integration/pom.xml 4(+3 -1)
testsuite/integration/src/test/java/org/keycloak/testsuite/broker/SAMLKeyCloakServerBrokerWithSignatureTest.java 5(+5 -0)
testsuite/integration/src/test/java/org/keycloak/testsuite/federation/FederationProvidersIntegrationTest.java 4(+1 -3)
testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserFederationModelTest.java 41(+41 -0)
testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java 1(+1 -0)
testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/ResourceOwnerPasswordCredentialsGrantTest.java 26(+26 -0)
testsuite/integration/src/test/java/org/keycloak/testsuite/offlineconfig/AdminRecoveryTest.java 133(+133 -0)
testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/fragment/Navigation.java 99(+50 -49)
testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/user/RoleMappingsPage.java 71(+71 -0)
testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/user/UserPage.java 2(+1 -1)
testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/role/AddNewRoleTest.java 82(+40 -42)
testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/user/AddNewUserTest.java 11(+7 -4)
testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/user/RegisterNewUserTest.java 2(+1 -1)
testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/user/RoleMappingsTest.java 72(+72 -0)
testsuite/jetty/jetty81/pom.xml 2(+1 -1)
testsuite/jetty/jetty91/pom.xml 2(+1 -1)
testsuite/jetty/jetty92/pom.xml 2(+1 -1)
testsuite/performance/pom.xml 2(+1 -1)
testsuite/pom.xml 34(+33 -1)
testsuite/proxy/pom.xml 2(+1 -1)
testsuite/tomcat6/pom.xml 2(+1 -1)
testsuite/tomcat7/pom.xml 2(+1 -1)
testsuite/tomcat8/pom.xml 2(+1 -1)
timer/api/pom.xml 2(+1 -1)
timer/basic/pom.xml 2(+1 -1)
timer/pom.xml 2(+1 -1)
Details
broker/core/pom.xml 2(+1 -1)
diff --git a/broker/core/pom.xml b/broker/core/pom.xml
index 41d236e..ab121a7 100755
--- a/broker/core/pom.xml
+++ b/broker/core/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/broker/core/src/main/java/org/keycloak/broker/provider/IdentityProvider.java b/broker/core/src/main/java/org/keycloak/broker/provider/IdentityProvider.java
index 47037fa..1d775ee 100755
--- a/broker/core/src/main/java/org/keycloak/broker/provider/IdentityProvider.java
+++ b/broker/core/src/main/java/org/keycloak/broker/provider/IdentityProvider.java
@@ -36,7 +36,7 @@ import javax.ws.rs.core.UriInfo;
*/
public interface IdentityProvider<C extends IdentityProviderModel> extends Provider {
- public interface AuthenticationCallback {
+ interface AuthenticationCallback {
/**
* This method should be called by provider after the JAXRS callback endpoint has finished authentication
* with the remote IDP
@@ -44,7 +44,11 @@ public interface IdentityProvider<C extends IdentityProviderModel> extends Provi
* @param context
* @return
*/
- public Response authenticated(BrokeredIdentityContext context);
+ Response authenticated(BrokeredIdentityContext context);
+
+ Response cancelled(String code);
+
+ Response error(String code, String message);
}
broker/oidc/pom.xml 2(+1 -1)
diff --git a/broker/oidc/pom.xml b/broker/oidc/pom.xml
index 982a63c..f3be798 100755
--- a/broker/oidc/pom.xml
+++ b/broker/oidc/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/broker/oidc/src/main/java/org/keycloak/broker/oidc/AbstractOAuth2IdentityProvider.java b/broker/oidc/src/main/java/org/keycloak/broker/oidc/AbstractOAuth2IdentityProvider.java
index b80949a..376210d 100755
--- a/broker/oidc/src/main/java/org/keycloak/broker/oidc/AbstractOAuth2IdentityProvider.java
+++ b/broker/oidc/src/main/java/org/keycloak/broker/oidc/AbstractOAuth2IdentityProvider.java
@@ -58,6 +58,7 @@ public abstract class AbstractOAuth2IdentityProvider<C extends OAuth2IdentityPro
public static final String FEDERATED_ACCESS_TOKEN = "FEDERATED_ACCESS_TOKEN";
public static final String FEDERATED_REFRESH_TOKEN = "FEDERATED_REFRESH_TOKEN";
public static final String FEDERATED_TOKEN_EXPIRATION = "FEDERATED_TOKEN_EXPIRATION";
+ public static final String ACCESS_DENIED = "access_denied";
protected static ObjectMapper mapper = new ObjectMapper();
public static final String OAUTH2_PARAMETER_ACCESS_TOKEN = "access_token";
@@ -213,9 +214,11 @@ public abstract class AbstractOAuth2IdentityProvider<C extends OAuth2IdentityPro
@QueryParam(OAuth2Constants.ERROR) String error) {
if (error != null) {
//logger.error("Failed " + getConfig().getAlias() + " broker login: " + error);
- event.event(EventType.LOGIN);
- event.error(error);
- return ErrorPage.error(session, Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR);
+ if (error.equals(ACCESS_DENIED)) {
+ return callback.cancelled(state);
+ } else {
+ return callback.error(state, Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR);
+ }
}
try {
diff --git a/broker/oidc/src/main/java/org/keycloak/broker/oidc/mappers/AbstractJsonUserAttributeMapper.java b/broker/oidc/src/main/java/org/keycloak/broker/oidc/mappers/AbstractJsonUserAttributeMapper.java
new file mode 100755
index 0000000..9f5085e
--- /dev/null
+++ b/broker/oidc/src/main/java/org/keycloak/broker/oidc/mappers/AbstractJsonUserAttributeMapper.java
@@ -0,0 +1,206 @@
+package org.keycloak.broker.oidc.mappers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.codehaus.jackson.JsonNode;
+import org.jboss.logging.Logger;
+import org.keycloak.broker.oidc.OIDCIdentityProvider;
+import org.keycloak.broker.provider.AbstractIdentityProviderMapper;
+import org.keycloak.broker.provider.BrokeredIdentityContext;
+import org.keycloak.models.IdentityProviderMapperModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.provider.ProviderConfigProperty;
+
+/**
+ * Abstract class for Social Provider mappers which allow mapping of JSON user profile field into Keycloak user
+ * attribute. Concrete mapper classes with own ID and provider mapping must be implemented for each social provider who
+ * uses {@link JsonNode} user profile.
+ *
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public abstract class AbstractJsonUserAttributeMapper extends AbstractIdentityProviderMapper {
+
+
+ protected static final Logger logger = Logger.getLogger(AbstractJsonUserAttributeMapper.class);
+
+ protected static final Logger LOGGER_DUMP_USER_PROFILE = Logger.getLogger("org.keycloak.social.user_profile_dump");
+
+ private static final String JSON_PATH_DELIMITER = ".";
+
+ /**
+ * Config param where name of mapping source JSON User Profile field is stored.
+ */
+ public static final String CONF_JSON_FIELD = "jsonField";
+ /**
+ * Config param where name of mapping target USer attribute is stored.
+ */
+ public static final String CONF_USER_ATTRIBUTE = "userAttribute";
+
+ /**
+ * Key in {@link BrokeredIdentityContext#getContextData()} where {@link JsonNode} with user profile is stored.
+ */
+ public static final String CONTEXT_JSON_NODE = OIDCIdentityProvider.USER_INFO;
+
+ private static final List<ProviderConfigProperty> configProperties = new ArrayList<ProviderConfigProperty>();
+
+ static {
+ ProviderConfigProperty property;
+ ProviderConfigProperty property1;
+ property1 = new ProviderConfigProperty();
+ property1.setName(CONF_JSON_FIELD);
+ property1.setLabel("Social Profile JSON Field Path");
+ property1.setHelpText("Path of field in Social provider User Profile JSON data to get value from. You can use dot notation for nesting and square brackets for array index. Eg. 'contact.address[0].country'.");
+ property1.setType(ProviderConfigProperty.STRING_TYPE);
+ configProperties.add(property1);
+ property = new ProviderConfigProperty();
+ property.setName(CONF_USER_ATTRIBUTE);
+ property.setLabel("User Attribute Name");
+ property.setHelpText("User attribute name to store information into.");
+ property.setType(ProviderConfigProperty.STRING_TYPE);
+ configProperties.add(property);
+ }
+
+ /**
+ * Store used profile JsonNode into user context for later use by this mapper. Profile data are dumped into special logger if enabled also to allow investigation of the structure.
+ *
+ * @param user context to store profile data into
+ * @param profile to store into context
+ * @param provider identification of social provider to be used in log dump
+ *
+ * @see #importNewUser(KeycloakSession, RealmModel, UserModel, IdentityProviderMapperModel, BrokeredIdentityContext)
+ * @see BrokeredIdentityContext#getContextData()
+ */
+ public static void storeUserProfileForMapper(BrokeredIdentityContext user, JsonNode profile, String provider) {
+ user.getContextData().put(AbstractJsonUserAttributeMapper.CONTEXT_JSON_NODE, profile);
+ if (LOGGER_DUMP_USER_PROFILE.isDebugEnabled())
+ LOGGER_DUMP_USER_PROFILE.debug("User Profile JSON Data for provider "+provider+": " + profile);
+ }
+
+ @Override
+ public List<ProviderConfigProperty> getConfigProperties() {
+ return configProperties;
+ }
+
+ @Override
+ public String getDisplayCategory() {
+ return "Attribute Importer";
+ }
+
+ @Override
+ public String getDisplayType() {
+ return "Attribute Importer";
+ }
+
+ @Override
+ public String getHelpText() {
+ return "Import user profile information if it exists in Social provider JSON data into the specified user attribute.";
+ }
+
+ @Override
+ public void importNewUser(KeycloakSession session, RealmModel realm, UserModel user, IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) {
+ String attribute = mapperModel.getConfig().get(CONF_USER_ATTRIBUTE);
+ if (attribute == null || attribute.trim().isEmpty()) {
+ logger.debug("Attribute is not configured");
+ return;
+ }
+ attribute = attribute.trim();
+
+ String value = getJsonValue(mapperModel, context);
+ if (value != null) {
+ user.setAttribute(attribute, value);
+ }
+ }
+
+ @Override
+ public void updateBrokeredUser(KeycloakSession session, RealmModel realm, UserModel user, IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) {
+ // we do not update user profile from social provider
+ }
+
+ protected static String getJsonValue(IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) {
+
+ String jsonField = mapperModel.getConfig().get(CONF_JSON_FIELD);
+ if (jsonField == null || jsonField.trim().isEmpty()) {
+ logger.debug("JSON field path is not configured");
+ return null;
+ }
+ jsonField = jsonField.trim();
+
+ if (jsonField.startsWith(JSON_PATH_DELIMITER) || jsonField.endsWith(JSON_PATH_DELIMITER) || jsonField.startsWith("[")) {
+ logger.debug("JSON field path is invalid " + jsonField);
+ return null;
+ }
+
+ JsonNode profileJsonNode = (JsonNode) context.getContextData().get(CONTEXT_JSON_NODE);
+
+ String value = getJsonValue(profileJsonNode, jsonField);
+
+ if (value == null) {
+ logger.debug("User profile JSON value '" + jsonField + "' is not available.");
+ }
+
+ return value;
+ }
+
+ protected static String getJsonValue(JsonNode baseNode, String fieldPath) {
+ logger.debug("Going to process JsonNode path " + fieldPath + " on data " + baseNode);
+ if (baseNode != null) {
+
+ int idx = fieldPath.indexOf(JSON_PATH_DELIMITER);
+
+ String currentFieldName = fieldPath;
+ if (idx > 0) {
+ currentFieldName = fieldPath.substring(0, idx).trim();
+ if (currentFieldName.isEmpty()) {
+ logger.debug("JSON path is invalid " + fieldPath);
+ return null;
+ }
+ }
+
+ String currentNodeName = currentFieldName;
+ int arrayIndex = -1;
+ if (currentFieldName.endsWith("]")) {
+ int bi = currentFieldName.indexOf("[");
+ if (bi == -1) {
+ logger.debug("Invalid array index construct in " + currentFieldName);
+ return null;
+ }
+ try {
+ String is = currentFieldName.substring(bi+1, currentFieldName.length() - 1).trim();
+ arrayIndex = Integer.parseInt(is);
+ } catch (Exception e) {
+ logger.debug("Invalid array index construct in " + currentFieldName);
+ return null;
+ }
+ currentNodeName = currentFieldName.substring(0,bi).trim();
+ }
+
+ JsonNode currentNode = baseNode.get(currentNodeName);
+ if (arrayIndex > -1 && currentNode.isArray()) {
+ logger.debug("Going to take array node at index " + arrayIndex);
+ currentNode = currentNode.get(arrayIndex);
+ }
+
+ if (currentNode == null) {
+ logger.debug("JsonNode not found for name " + currentFieldName);
+ return null;
+ }
+
+ if (idx < 0) {
+ if (!currentNode.isValueNode()) {
+ logger.debug("JsonNode is not value node for name " + currentFieldName);
+ return null;
+ }
+ String ret = currentNode.asText();
+ if (ret != null && !ret.trim().isEmpty())
+ return ret.trim();
+ } else {
+ return getJsonValue(currentNode, fieldPath.substring(idx + 1));
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/broker/oidc/src/main/java/org/keycloak/broker/oidc/OIDCIdentityProvider.java b/broker/oidc/src/main/java/org/keycloak/broker/oidc/OIDCIdentityProvider.java
index 01e6c41..c576a5d 100755
--- a/broker/oidc/src/main/java/org/keycloak/broker/oidc/OIDCIdentityProvider.java
+++ b/broker/oidc/src/main/java/org/keycloak/broker/oidc/OIDCIdentityProvider.java
@@ -19,6 +19,7 @@ package org.keycloak.broker.oidc;
import org.codehaus.jackson.JsonNode;
import org.jboss.logging.Logger;
+import org.keycloak.broker.oidc.mappers.AbstractJsonUserAttributeMapper;
import org.keycloak.broker.oidc.util.JsonSimpleHttp;
import org.keycloak.broker.provider.util.SimpleHttp;
import org.keycloak.broker.provider.AuthenticationRequest;
@@ -50,6 +51,7 @@ import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
+
import java.io.IOException;
import java.security.PublicKey;
@@ -224,7 +226,7 @@ public class OIDCIdentityProvider extends AbstractOAuth2IdentityProvider<OIDCIde
name = getJsonProperty(userInfo, "name");
preferredUsername = getJsonProperty(userInfo, "preferred_username");
email = getJsonProperty(userInfo, "email");
- identity.getContextData().put(USER_INFO, userInfo);
+ AbstractJsonUserAttributeMapper.storeUserProfileForMapper(identity, userInfo, getConfig().getAlias());
}
identity.getContextData().put(FEDERATED_ACCESS_TOKEN_RESPONSE, tokenResponse);
identity.getContextData().put(VALIDATED_ID_TOKEN, idToken);
diff --git a/broker/oidc/src/test/java/org/keycloak/broker/oidc/mappers/AbstractJsonUserAttributeMapperTest.java b/broker/oidc/src/test/java/org/keycloak/broker/oidc/mappers/AbstractJsonUserAttributeMapperTest.java
new file mode 100644
index 0000000..dcd1abe
--- /dev/null
+++ b/broker/oidc/src/test/java/org/keycloak/broker/oidc/mappers/AbstractJsonUserAttributeMapperTest.java
@@ -0,0 +1,120 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2015 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @authors tag. All rights reserved.
+ */
+package org.keycloak.broker.oidc.mappers;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Unit test for {@link AbstractJsonUserAttributeMapper}
+ *
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class AbstractJsonUserAttributeMapperTest {
+
+ private static ObjectMapper mapper = new ObjectMapper();
+
+ private static JsonNode baseNode;
+
+ private JsonNode getJsonNode() throws JsonProcessingException, IOException {
+ if (baseNode == null)
+ baseNode = mapper.readTree("{ \"value1\" : \"v1 \",\"value_empty\" : \"\", \"value_b\" : true, \"value_i\" : 454, " + " \"value_array\":[\"a1\",\"a2\"], " +" \"nest1\": {\"value1\": \" fgh \",\"value_empty\" : \"\", \"nest2\":{\"value_b\" : false, \"value_i\" : 43}}, "+ " \"nesta\": { \"a\":[{\"av1\": \"vala1\"},{\"av1\": \"vala2\"}]}"+" }");
+ return baseNode;
+ }
+
+ @Test
+ public void getJsonValue_invalidPath() throws JsonProcessingException, IOException {
+
+ Assert.assertNull(AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "."));
+ Assert.assertNull(AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), ".."));
+ Assert.assertNull(AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "...value1"));
+ Assert.assertNull(AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), ".value1"));
+ Assert.assertNull(AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "value1."));
+ Assert.assertNull(AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "[]"));
+ Assert.assertNull(AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "[value1"));
+ }
+
+ @Test
+ public void getJsonValue_simpleValues() throws JsonProcessingException, IOException {
+
+ //unknown field returns null
+ Assert.assertEquals(null, AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "value_unknown"));
+
+ // we check value is trimmed also!
+ Assert.assertEquals("v1", AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "value1"));
+ Assert.assertEquals(null, AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "value_empty"));
+
+ Assert.assertEquals("true", AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "value_b"));
+ Assert.assertEquals("454", AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "value_i"));
+
+ }
+
+ @Test
+ public void getJsonValue_nestedSimpleValues() throws JsonProcessingException, IOException {
+
+ // null if path points to JSON object
+ Assert.assertEquals(null, AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "nest1"));
+ Assert.assertEquals(null, AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "nest1.nest2"));
+
+ //unknown field returns null
+ Assert.assertEquals(null, AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "nest1.value_unknown"));
+ Assert.assertEquals(null, AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "nest1.nest2.value_unknown"));
+
+ // we check value is trimmed also!
+ Assert.assertEquals("fgh", AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "nest1.value1"));
+ Assert.assertEquals(null, AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "nest1.value_empty"));
+
+ Assert.assertEquals("false", AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "nest1.nest2.value_b"));
+ Assert.assertEquals("43", AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "nest1.nest2.value_i"));
+
+ // null if invalid nested path
+ Assert.assertNull(AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "nest1."));
+ Assert.assertNull(AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "nest1.nest2."));
+ }
+
+ @Test
+ public void getJsonValue_simpleArray() throws JsonProcessingException, IOException {
+
+ // array field itself returns null if no index is provided
+ Assert.assertEquals(null, AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "value_array"));
+ // outside index returns null
+ Assert.assertEquals(null, AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "value_array[2]"));
+
+ //corect index
+ Assert.assertEquals("a1", AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "value_array[0]"));
+ Assert.assertEquals("a2", AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "value_array[1]"));
+
+ //incorrect array constructs
+ Assert.assertNull(AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "value_array[]"));
+ Assert.assertNull(AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "value_array]"));
+ Assert.assertNull(AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "value_array["));
+ Assert.assertNull(AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "value_array[a]"));
+ Assert.assertNull(AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "value_array[-2]"));
+ }
+
+ @Test
+ public void getJsonValue_nestedArrayWithObjects() throws JsonProcessingException, IOException {
+ Assert.assertEquals("vala1", AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "nesta.a[0].av1"));
+ Assert.assertEquals("vala2", AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "nesta.a[1].av1"));
+
+ //different path erros or nonexisting indexes or fields return null
+ Assert.assertEquals(null, AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "nesta.a[2].av1"));
+ Assert.assertEquals(null, AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "nesta.a[0]"));
+ Assert.assertEquals(null, AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "nesta.a[0].av_unknown"));
+ Assert.assertEquals(null, AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "nesta.a[].av1"));
+ Assert.assertEquals(null, AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "nesta.a"));
+ Assert.assertEquals(null, AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "nesta.a.av1"));
+ Assert.assertEquals(null, AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "nesta.a].av1"));
+ Assert.assertEquals(null, AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "nesta.a[.av1"));
+
+ }
+
+}
broker/pom.xml 2(+1 -1)
diff --git a/broker/pom.xml b/broker/pom.xml
index 489e16c..885206e 100755
--- a/broker/pom.xml
+++ b/broker/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
broker/saml/pom.xml 2(+1 -1)
diff --git a/broker/saml/pom.xml b/broker/saml/pom.xml
index f87fb51..dfeeb11 100755
--- a/broker/saml/pom.xml
+++ b/broker/saml/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
connections/file/pom.xml 2(+1 -1)
diff --git a/connections/file/pom.xml b/connections/file/pom.xml
index 13e3e6c..48464e9 100755
--- a/connections/file/pom.xml
+++ b/connections/file/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
connections/http-client/pom.xml 2(+1 -1)
diff --git a/connections/http-client/pom.xml b/connections/http-client/pom.xml
index 2306cf7..d580be5 100755
--- a/connections/http-client/pom.xml
+++ b/connections/http-client/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
connections/infinispan/pom.xml 2(+1 -1)
diff --git a/connections/infinispan/pom.xml b/connections/infinispan/pom.xml
index 8febd5b..a2b3791 100755
--- a/connections/infinispan/pom.xml
+++ b/connections/infinispan/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
connections/jpa/pom.xml 2(+1 -1)
diff --git a/connections/jpa/pom.xml b/connections/jpa/pom.xml
index 1ef75f2..7dd5f3a 100755
--- a/connections/jpa/pom.xml
+++ b/connections/jpa/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/connections/jpa/src/main/java/org/keycloak/connections/jpa/updater/JpaUpdaterProvider.java b/connections/jpa/src/main/java/org/keycloak/connections/jpa/updater/JpaUpdaterProvider.java
index ad41016..809f2f3 100755
--- a/connections/jpa/src/main/java/org/keycloak/connections/jpa/updater/JpaUpdaterProvider.java
+++ b/connections/jpa/src/main/java/org/keycloak/connections/jpa/updater/JpaUpdaterProvider.java
@@ -12,7 +12,7 @@ public interface JpaUpdaterProvider extends Provider {
public String FIRST_VERSION = "1.0.0.Final";
- public String LAST_VERSION = "1.3.0.Beta1";
+ public String LAST_VERSION = "1.4.0";
public String getCurrentVersionSql();
connections/jpa-liquibase/pom.xml 4(+2 -2)
diff --git a/connections/jpa-liquibase/pom.xml b/connections/jpa-liquibase/pom.xml
index 37e921e..01a090b 100755
--- a/connections/jpa-liquibase/pom.xml
+++ b/connections/jpa-liquibase/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -54,7 +54,7 @@
<configuration>
<changeLogFile>META-INF/jpa-changelog-master.xml</changeLogFile>
- <url>${url}</url>
+ <url>${project.url}</url>
<driver>${driver}</driver>
<username>${username}</username>
<password>${password}</password>
diff --git a/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate1_2_0_CR1.java b/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate1_2_0_CR1.java
index 5c8a2eb..00f9b0c 100644
--- a/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate1_2_0_CR1.java
+++ b/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate1_2_0_CR1.java
@@ -3,6 +3,7 @@ package org.keycloak.connections.jpa.updater.liquibase.custom;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
+import liquibase.datatype.DataTypeFactory;
import liquibase.exception.CustomChangeException;
import liquibase.statement.core.InsertStatement;
import liquibase.structure.core.Table;
@@ -17,7 +18,9 @@ public class JpaUpdate1_2_0_CR1 extends CustomKeycloakTask {
String realmClientTableName = database.correctObjectName("REALM_CLIENT", Table.class);
try {
- PreparedStatement statement = jdbcConnection.prepareStatement("select CLIENT.REALM_ID, CLIENT.ID CLIENT_ID from CLIENT where CLIENT.CONSENT_REQUIRED = true");
+ String trueValue = DataTypeFactory.getInstance().getTrueBooleanValue(database);
+ PreparedStatement statement = jdbcConnection.prepareStatement("select CLIENT.REALM_ID, CLIENT.ID CLIENT_ID from CLIENT where CLIENT.CONSENT_REQUIRED = " + trueValue);
+
try {
ResultSet resultSet = statement.executeQuery();
try {
diff --git a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.4.0.xml b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.4.0.xml
new file mode 100755
index 0000000..80f0e36
--- /dev/null
+++ b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.4.0.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
+ <changeSet author="bburke@redhat.com" id="1.4.0">
+ <delete tableName="CLIENT_SESSION_AUTH_STATUS"/>
+ <delete tableName="CLIENT_SESSION_PROT_MAPPER"/>
+ <delete tableName="CLIENT_SESSION_NOTE"/>
+ <delete tableName="CLIENT_SESSION"/>
+ <delete tableName="USER_SESSION_NOTE"/>
+ <delete tableName="USER_SESSION"/>
+ <createTable tableName="DEFAULT_REQUIRED_ACTIONS">
+ <column name="REALM_ID" type="VARCHAR(36)">
+ <constraints nullable="false"/>
+ </column>
+ <column name="VALUE" type="VARCHAR(36)"/>
+ </createTable>
+ <addColumn tableName="CLIENT_SESSION">
+ <column name="CURRENT_ACTION" type="VARCHAR(36)">
+ <constraints nullable="false"/>
+ </column>
+ </addColumn>
+ <!-- OAUTH_GRANT,
+ CODE_TO_TOKEN,
+ VERIFY_EMAIL,
+ UPDATE_PROFILE,
+ CONFIGURE_TOTP,
+ UPDATE_PASSWORD,
+ RECOVER_PASSWORD,
+ AUTHENTICATE,
+ SOCIAL_CALLBACK,
+ LOGGED_OUT -->
+ <update tableName="CLIENT_SESSION">
+ <column name="CURRENT_ACTION" value="OAUTH_GRANT"/>
+ <where>ACTION = 0</where>
+ </update>
+ <update tableName="CLIENT_SESSION">
+ <column name="CURRENT_ACTION" value="CODE_TO_TOKEN"/>
+ <where>ACTION = 1</where>
+ </update>
+ <update tableName="CLIENT_SESSION">
+ <column name="CURRENT_ACTION" value="VERIFY_EMAIL"/>
+ <where>ACTION = 2</where>
+ </update>
+ <update tableName="CLIENT_SESSION">
+ <column name="CURRENT_ACTION" value="UPDATE_PROFILE"/>
+ <where>ACTION = 3</where>
+ </update>
+ <update tableName="CLIENT_SESSION">
+ <column name="CURRENT_ACTION" value="CONFIGURE_TOTP"/>
+ <where>ACTION = 4</where>
+ </update>
+ <update tableName="CLIENT_SESSION">
+ <column name="CURRENT_ACTION" value="UPDATE_PASSWORD"/>
+ <where>ACTION = 5</where>
+ </update>
+ <update tableName="CLIENT_SESSION">
+ <column name="CURRENT_ACTION" value="RECOVER_PASSWORD"/>
+ <where>ACTION = 6</where>
+ </update>
+ <update tableName="CLIENT_SESSION">
+ <column name="CURRENT_ACTION" value="AUTHENTICATE"/>
+ <where>ACTION = 7</where>
+ </update>
+ <update tableName="CLIENT_SESSION">
+ <column name="CURRENT_ACTION" value="SOCIAL_CALLBACK"/>
+ <where>ACTION = 8</where>
+ </update>
+ <update tableName="CLIENT_SESSION">
+ <column name="CURRENT_ACTION" value="LOGGED_OUT"/>
+ <where>ACTION = 9</where>
+ </update>
+
+ <createTable tableName="CLIENT_USER_SESSION_NOTE">
+ <column name="NAME" type="VARCHAR(255)">
+ <constraints nullable="false"/>
+ </column>
+ <column name="VALUE" type="VARCHAR(255)"/>
+ <column name="CLIENT_SESSION" type="VARCHAR(36)">
+ <constraints nullable="false"/>
+ </column>
+ </createTable>
+ <addPrimaryKey columnNames="CLIENT_SESSION, NAME" constraintName="CONSTR_CL_USR_SES_NOTE" tableName="CLIENT_USER_SESSION_NOTE"/>
+ <addForeignKeyConstraint baseColumnNames="CLIENT_SESSION" baseTableName="CLIENT_USER_SESSION_NOTE" constraintName="FK_CL_USR_SES_NOTE" referencedColumnNames="ID" referencedTableName="CLIENT_SESSION"/>
+ <dropColumn tableName="CLIENT_SESSION" columnName="ACTION"/>
+ <addForeignKeyConstraint baseColumnNames="REALM_ID" baseTableName="DEFAULT_REQUIRED_ACTIONS" constraintName="FK_DEF_REQ_ACTS_REALM" referencedColumnNames="ID" referencedTableName="REALM"/>
+ </changeSet>
+</databaseChangeLog>
diff --git a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-master.xml b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-master.xml
index 76c4507..efba42c 100755
--- a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-master.xml
+++ b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-master.xml
@@ -6,5 +6,6 @@
<include file="META-INF/jpa-changelog-1.2.0.Beta1.xml"/>
<include file="META-INF/jpa-changelog-1.2.0.CR1.xml"/>
<include file="META-INF/jpa-changelog-1.2.0.Final.xml"/>
- <include file="META-INF/jpa-changelog-1.3.0.Beta1.xml"/>
+ <include file="META-INF/jpa-changelog-1.3.0.xml"/>
+ <include file="META-INF/jpa-changelog-1.4.0.xml"/>
</databaseChangeLog>
connections/mongo/pom.xml 2(+1 -1)
diff --git a/connections/mongo/pom.xml b/connections/mongo/pom.xml
index 2497188..af87da8 100755
--- a/connections/mongo/pom.xml
+++ b/connections/mongo/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
connections/mongo-update/pom.xml 2(+1 -1)
diff --git a/connections/mongo-update/pom.xml b/connections/mongo-update/pom.xml
index a3a1eae..eec00b8 100755
--- a/connections/mongo-update/pom.xml
+++ b/connections/mongo-update/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/DefaultMongoUpdaterProvider.java b/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/DefaultMongoUpdaterProvider.java
index c8097f6..3ca2bff 100644
--- a/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/DefaultMongoUpdaterProvider.java
+++ b/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/DefaultMongoUpdaterProvider.java
@@ -27,7 +27,7 @@ public class DefaultMongoUpdaterProvider implements MongoUpdaterProvider {
Update1_1_0_Beta1.class,
Update1_2_0_Beta1.class,
Update1_2_0_CR1.class,
- Update1_3_0_Beta1.class
+ Update1_3_0.class
};
@Override
diff --git a/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update1_3_0.java b/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update1_3_0.java
new file mode 100644
index 0000000..b227333
--- /dev/null
+++ b/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update1_3_0.java
@@ -0,0 +1,59 @@
+package org.keycloak.connections.mongo.updater.impl.updates;
+
+import com.mongodb.BasicDBList;
+import com.mongodb.BasicDBObject;
+import com.mongodb.DBCollection;
+import com.mongodb.DBCursor;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.representations.idm.IdentityProviderRepresentation;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class Update1_3_0 extends Update {
+
+ @Override
+ public String getId() {
+ return "1.3.0";
+ }
+
+ @Override
+ public void update(KeycloakSession session) {
+ deleteEntries("clientSessions");
+ deleteEntries("sessions");
+
+ removeField("realms", "passwordCredentialGrantAllowed");
+
+ updateIdentityProviders();
+ }
+
+ private void updateIdentityProviders() {
+ DBCollection realms = db.getCollection("realms");
+ DBCursor realmsCursor = realms.find();
+
+ try {
+ while (realmsCursor.hasNext()) {
+ BasicDBObject realm = (BasicDBObject) realmsCursor.next();
+
+ BasicDBList identityProviders = (BasicDBList) realm.get("identityProviders");
+ if (identityProviders != null) {
+ for (Object ipObj : identityProviders) {
+ BasicDBObject identityProvider = (BasicDBObject) ipObj;
+
+ boolean updateProfileFirstLogin = identityProvider.getBoolean("updateProfileFirstLogin");
+ String upflMode = updateProfileFirstLogin ? IdentityProviderRepresentation.UPFLM_ON : IdentityProviderRepresentation.UPFLM_OFF;
+ identityProvider.put("updateProfileFirstLoginMode", upflMode);
+ identityProvider.removeField("updateProfileFirstLogin");
+
+ identityProvider.put("trustEmail", false);
+ }
+ }
+
+ realms.save(realm);
+ }
+ } finally {
+ realmsCursor.close();
+ }
+ }
+
+}
connections/pom.xml 2(+1 -1)
diff --git a/connections/pom.xml b/connections/pom.xml
index 5139c00..a300c30 100755
--- a/connections/pom.xml
+++ b/connections/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<name>Connections Parent</name>
<description/>
core/pom.xml 2(+1 -1)
diff --git a/core/pom.xml b/core/pom.xml
index 9cbe5bd..5a12d1b 100755
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
index 3443f4f..dabc8db 100755
--- a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
@@ -266,6 +266,10 @@ public class RealmRepresentation {
this.codeSecret = codeSecret;
}
+ public Boolean isPasswordCredentialGrantAllowed() {
+ return passwordCredentialGrantAllowed;
+ }
+
public Boolean isRegistrationAllowed() {
return registrationAllowed;
}
diff --git a/core/src/main/java/org/keycloak/util/HtmlUtils.java b/core/src/main/java/org/keycloak/util/HtmlUtils.java
old mode 100644
new mode 100755
index 7da97b7..2387482
--- a/core/src/main/java/org/keycloak/util/HtmlUtils.java
+++ b/core/src/main/java/org/keycloak/util/HtmlUtils.java
@@ -34,7 +34,17 @@ public class HtmlUtils {
for (int i = 0; i < value.length(); i++) {
char chr = value.charAt(i);
- if (chr != '\'' && chr != '"' && chr != '<' && chr != '>' && chr != '/') {
+ if (chr == '<') {
+ escaped.append("<");
+ } else if (chr == '>') {
+ escaped.append(">");
+ } else if (chr == '"') {
+ escaped.append(""");
+ } else if (chr == '\'') {
+ escaped.append("'");
+ } else if (chr == '&') {
+ escaped.append("&");
+ } else {
escaped.append(chr);
}
}
core-jaxrs/pom.xml 2(+1 -1)
diff --git a/core-jaxrs/pom.xml b/core-jaxrs/pom.xml
index 5a8b2c8..78bf93d 100755
--- a/core-jaxrs/pom.xml
+++ b/core-jaxrs/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
dependencies/pom.xml 2(+1 -1)
diff --git a/dependencies/pom.xml b/dependencies/pom.xml
index 374a4f8..692d4a5 100755
--- a/dependencies/pom.xml
+++ b/dependencies/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
dependencies/server-all/pom.xml 2(+1 -1)
diff --git a/dependencies/server-all/pom.xml b/dependencies/server-all/pom.xml
index 707933a..c813be8 100755
--- a/dependencies/server-all/pom.xml
+++ b/dependencies/server-all/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
dependencies/server-min/pom.xml 2(+1 -1)
diff --git a/dependencies/server-min/pom.xml b/dependencies/server-min/pom.xml
index ae24777..009742e 100755
--- a/dependencies/server-min/pom.xml
+++ b/dependencies/server-min/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/distribution/adapters/as7-eap6-adapter/as7-adapter-zip/pom.xml b/distribution/adapters/as7-eap6-adapter/as7-adapter-zip/pom.xml
index 5792a46..e70bd6f 100755
--- a/distribution/adapters/as7-eap6-adapter/as7-adapter-zip/pom.xml
+++ b/distribution/adapters/as7-eap6-adapter/as7-adapter-zip/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
diff --git a/distribution/adapters/as7-eap6-adapter/as7-modules/pom.xml b/distribution/adapters/as7-eap6-adapter/as7-modules/pom.xml
index 694fd45..6fb1671 100755
--- a/distribution/adapters/as7-eap6-adapter/as7-modules/pom.xml
+++ b/distribution/adapters/as7-eap6-adapter/as7-modules/pom.xml
@@ -8,7 +8,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
@@ -56,7 +56,6 @@
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
- <version>${bouncycastle.crypto.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
diff --git a/distribution/adapters/as7-eap6-adapter/eap6-adapter-zip/pom.xml b/distribution/adapters/as7-eap6-adapter/eap6-adapter-zip/pom.xml
index 96dc3c6..91bfc36 100755
--- a/distribution/adapters/as7-eap6-adapter/eap6-adapter-zip/pom.xml
+++ b/distribution/adapters/as7-eap6-adapter/eap6-adapter-zip/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
diff --git a/distribution/adapters/as7-eap6-adapter/pom.xml b/distribution/adapters/as7-eap6-adapter/pom.xml
index 08808f8..e999582 100644
--- a/distribution/adapters/as7-eap6-adapter/pom.xml
+++ b/distribution/adapters/as7-eap6-adapter/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<name>Keycloak AS7 / JBoss EAP 6 Adapter Distros</name>
diff --git a/distribution/adapters/jetty81-adapter-zip/pom.xml b/distribution/adapters/jetty81-adapter-zip/pom.xml
index 233d0ff..18e3a3b 100755
--- a/distribution/adapters/jetty81-adapter-zip/pom.xml
+++ b/distribution/adapters/jetty81-adapter-zip/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
diff --git a/distribution/adapters/jetty91-adapter-zip/pom.xml b/distribution/adapters/jetty91-adapter-zip/pom.xml
index 75b455b..5c47600 100755
--- a/distribution/adapters/jetty91-adapter-zip/pom.xml
+++ b/distribution/adapters/jetty91-adapter-zip/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
diff --git a/distribution/adapters/jetty92-adapter-zip/pom.xml b/distribution/adapters/jetty92-adapter-zip/pom.xml
index f26c50e..c3aeac0 100755
--- a/distribution/adapters/jetty92-adapter-zip/pom.xml
+++ b/distribution/adapters/jetty92-adapter-zip/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
diff --git a/distribution/adapters/js-adapter-zip/pom.xml b/distribution/adapters/js-adapter-zip/pom.xml
index 090d401..6934300 100755
--- a/distribution/adapters/js-adapter-zip/pom.xml
+++ b/distribution/adapters/js-adapter-zip/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
diff --git a/distribution/adapters/osgi/features/pom.xml b/distribution/adapters/osgi/features/pom.xml
index 850e2ed..2ef952e 100755
--- a/distribution/adapters/osgi/features/pom.xml
+++ b/distribution/adapters/osgi/features/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<name>Keycloak OSGI Features</name>
diff --git a/distribution/adapters/osgi/jaas/pom.xml b/distribution/adapters/osgi/jaas/pom.xml
index 9e79791..eb8a2ba 100755
--- a/distribution/adapters/osgi/jaas/pom.xml
+++ b/distribution/adapters/osgi/jaas/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<name>Keycloak OSGI JAAS Realm Configuration</name>
distribution/adapters/osgi/pom.xml 2(+1 -1)
diff --git a/distribution/adapters/osgi/pom.xml b/distribution/adapters/osgi/pom.xml
index dd73ecb..ddbfc32 100755
--- a/distribution/adapters/osgi/pom.xml
+++ b/distribution/adapters/osgi/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<name>Keycloak OSGI Integration</name>
diff --git a/distribution/adapters/osgi/thirdparty/pom.xml b/distribution/adapters/osgi/thirdparty/pom.xml
index 7a3546e..b61b09b 100755
--- a/distribution/adapters/osgi/thirdparty/pom.xml
+++ b/distribution/adapters/osgi/thirdparty/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
distribution/adapters/pom.xml 2(+1 -1)
diff --git a/distribution/adapters/pom.xml b/distribution/adapters/pom.xml
index f0070f8..dc8c8e8 100755
--- a/distribution/adapters/pom.xml
+++ b/distribution/adapters/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
diff --git a/distribution/adapters/tomcat6-adapter-zip/pom.xml b/distribution/adapters/tomcat6-adapter-zip/pom.xml
index 604fb26..26d555c 100755
--- a/distribution/adapters/tomcat6-adapter-zip/pom.xml
+++ b/distribution/adapters/tomcat6-adapter-zip/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
diff --git a/distribution/adapters/tomcat7-adapter-zip/pom.xml b/distribution/adapters/tomcat7-adapter-zip/pom.xml
index 89d336b..edb5ea7 100755
--- a/distribution/adapters/tomcat7-adapter-zip/pom.xml
+++ b/distribution/adapters/tomcat7-adapter-zip/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
diff --git a/distribution/adapters/tomcat8-adapter-zip/pom.xml b/distribution/adapters/tomcat8-adapter-zip/pom.xml
index a45c548..ce7a4f5 100755
--- a/distribution/adapters/tomcat8-adapter-zip/pom.xml
+++ b/distribution/adapters/tomcat8-adapter-zip/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
diff --git a/distribution/adapters/wf8-adapter/pom.xml b/distribution/adapters/wf8-adapter/pom.xml
index 7f71d64..016c293 100644
--- a/distribution/adapters/wf8-adapter/pom.xml
+++ b/distribution/adapters/wf8-adapter/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<name>Keycloak Wildfly 8 Adapter</name>
diff --git a/distribution/adapters/wf8-adapter/wf8-adapter-zip/pom.xml b/distribution/adapters/wf8-adapter/wf8-adapter-zip/pom.xml
index aa33dd3..226d2e6 100755
--- a/distribution/adapters/wf8-adapter/wf8-adapter-zip/pom.xml
+++ b/distribution/adapters/wf8-adapter/wf8-adapter-zip/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
diff --git a/distribution/adapters/wf8-adapter/wf8-modules/pom.xml b/distribution/adapters/wf8-adapter/wf8-modules/pom.xml
index cd3f3e3..0f88bb7 100755
--- a/distribution/adapters/wf8-adapter/wf8-modules/pom.xml
+++ b/distribution/adapters/wf8-adapter/wf8-modules/pom.xml
@@ -8,7 +8,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
diff --git a/distribution/adapters/wf9-adapter/pom.xml b/distribution/adapters/wf9-adapter/pom.xml
index 33f4d58..275c4e3 100644
--- a/distribution/adapters/wf9-adapter/pom.xml
+++ b/distribution/adapters/wf9-adapter/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<name>Keycloak Wildfly 9 Adapter</name>
diff --git a/distribution/adapters/wf9-adapter/wf9-adapter-zip/pom.xml b/distribution/adapters/wf9-adapter/wf9-adapter-zip/pom.xml
index 7d8ca7d..1854277 100755
--- a/distribution/adapters/wf9-adapter/wf9-adapter-zip/pom.xml
+++ b/distribution/adapters/wf9-adapter/wf9-adapter-zip/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
diff --git a/distribution/adapters/wf9-adapter/wf9-modules/pom.xml b/distribution/adapters/wf9-adapter/wf9-modules/pom.xml
index 55c4c94..b408d53 100755
--- a/distribution/adapters/wf9-adapter/wf9-modules/pom.xml
+++ b/distribution/adapters/wf9-adapter/wf9-modules/pom.xml
@@ -8,7 +8,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
distribution/demo-dist/assembly.xml 21(+20 -1)
diff --git a/distribution/demo-dist/assembly.xml b/distribution/demo-dist/assembly.xml
index f00bfea..5a6be78 100755
--- a/distribution/demo-dist/assembly.xml
+++ b/distribution/demo-dist/assembly.xml
@@ -14,7 +14,6 @@
<outputDirectory>keycloak</outputDirectory>
<excludes>
<exclude>**/*.sh</exclude>
- <exclude>standalone/configuration/standalone-keycloak.xml</exclude>
</excludes>
</fileSet>
<fileSet>
@@ -26,6 +25,20 @@
<fileMode>0755</fileMode>
</fileSet>
<fileSet>
+ <directory>${project.build.directory}/unpacked/keycloak-server-overlay-${project.version}</directory>
+ <outputDirectory>keycloak</outputDirectory>
+ <excludes>
+ <exclude>standalone/configuration/standalone-keycloak.xml</exclude>
+ </excludes>
+ </fileSet>
+ <fileSet>
+ <directory>${project.build.directory}/unpacked/keycloak-wf9-adapter-${project.version}</directory>
+ <outputDirectory>keycloak</outputDirectory>
+ <excludes>
+ <exclude>standalone/configuration/standalone-keycloak.xml</exclude>
+ </excludes>
+ </fileSet>
+ <fileSet>
<directory>${project.build.directory}/unpacked/keycloak-docs-${project.version}</directory>
<outputDirectory>docs</outputDirectory>
</fileSet>
@@ -34,5 +47,11 @@
<outputDirectory>examples</outputDirectory>
</fileSet>
</fileSets>
+ <files>
+ <file>
+ <source>${project.build.directory}/unpacked/standalone.xml</source>
+ <outputDirectory>keycloak/standalone/configuration</outputDirectory>
+ </file>
+ </files>
</assembly>
distribution/demo-dist/pom.xml 34(+28 -6)
diff --git a/distribution/demo-dist/pom.xml b/distribution/demo-dist/pom.xml
index 37e4bdc..f57344f 100755
--- a/distribution/demo-dist/pom.xml
+++ b/distribution/demo-dist/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
@@ -16,7 +16,12 @@
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
- <artifactId>keycloak-server-dist</artifactId>
+ <artifactId>keycloak-wf9-server-overlay</artifactId>
+ <type>zip</type>
+ </dependency>
+ <dependency>
+ <groupId>org.keycloak</groupId>
+ <artifactId>keycloak-wf9-adapter-dist</artifactId>
<type>zip</type>
</dependency>
<dependency>
@@ -63,7 +68,24 @@
</configuration>
</execution>
<execution>
- <id>unpack-server-overlay</id>
+ <id>unpack-server</id>
+ <phase>prepare-package</phase>
+ <goals>
+ <goal>unpack</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+ <groupId>org.keycloak</groupId>
+ <artifactId>keycloak-wf9-server-overlay</artifactId>
+ <type>zip</type>
+ <outputDirectory>${project.build.directory}/unpacked/keycloak-server-overlay-${project.version}</outputDirectory>
+ </artifactItem>
+ </artifactItems>
+ </configuration>
+ </execution>
+ <execution>
+ <id>unpack-adapter</id>
<phase>prepare-package</phase>
<goals>
<goal>unpack</goal>
@@ -72,9 +94,9 @@
<artifactItems>
<artifactItem>
<groupId>org.keycloak</groupId>
- <artifactId>keycloak-server-overlay</artifactId>
+ <artifactId>keycloak-wf9-adapter-dist</artifactId>
<type>zip</type>
- <outputDirectory>${project.build.directory}/unpacked/wildfly-${wildfly.version}</outputDirectory>
+ <outputDirectory>${project.build.directory}/unpacked/keycloak-wf9-adapter-${project.version}</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
@@ -134,7 +156,7 @@
<includes>
<include>standalone.xml</include>
</includes>
- <outputDir>${project.build.directory}/unpacked/wildfly-${wildfly.version}/standalone/configuration</outputDir>
+ <outputDir>${project.build.directory}/unpacked/</outputDir>
</transformationSet>
</transformationSets>
</configuration>
diff --git a/distribution/demo-dist/src/main/xslt/standalone.xsl b/distribution/demo-dist/src/main/xslt/standalone.xsl
index 5de72af..bc0233a 100755
--- a/distribution/demo-dist/src/main/xslt/standalone.xsl
+++ b/distribution/demo-dist/src/main/xslt/standalone.xsl
@@ -39,11 +39,9 @@
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
<subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
- <auth-server name="main-auth-server">
- <enabled>true</enabled>
- <web-context>auth</web-context>
- </auth-server>
+ <web-context>auth</web-context>
</subsystem>
+ <subsystem xmlns="urn:jboss:domain:keycloak:1.1"/>
</xsl:copy>
</xsl:template>
distribution/docs-dist/pom.xml 2(+1 -1)
diff --git a/distribution/docs-dist/pom.xml b/distribution/docs-dist/pom.xml
index 1f0f665..4cf67a5 100755
--- a/distribution/docs-dist/pom.xml
+++ b/distribution/docs-dist/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
distribution/examples-dist/pom.xml 2(+1 -1)
diff --git a/distribution/examples-dist/pom.xml b/distribution/examples-dist/pom.xml
index 3ffe6db..ae8dd06 100755
--- a/distribution/examples-dist/pom.xml
+++ b/distribution/examples-dist/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
distribution/feature-packs/pom.xml 2(+1 -1)
diff --git a/distribution/feature-packs/pom.xml b/distribution/feature-packs/pom.xml
index 06f0e5c..f5402ee 100644
--- a/distribution/feature-packs/pom.xml
+++ b/distribution/feature-packs/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>distribution-pom</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<name>Feature Pack Builds</name>
diff --git a/distribution/feature-packs/server-feature-pack/pom.xml b/distribution/feature-packs/server-feature-pack/pom.xml
index a737427..bafc79e 100644
--- a/distribution/feature-packs/server-feature-pack/pom.xml
+++ b/distribution/feature-packs/server-feature-pack/pom.xml
@@ -20,7 +20,7 @@
<parent>
<groupId>org.keycloak</groupId>
<artifactId>feature-packs-parent</artifactId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -34,31 +34,22 @@
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-dependencies-server-all</artifactId>
- <version>${project.version}</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.keycloak.subsystem</groupId>
<artifactId>keycloak-server</artifactId>
- <version>${project.version}</version>
<type>war</type>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
- <artifactId>keycloak-wildfly-server-subsystem</artifactId>
- <version>${project.version}</version>
- </dependency>
+ <artifactId>keycloak-wf9-server-subsystem</artifactId>
+ </dependency>
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-feature-pack</artifactId>
<type>zip</type>
</dependency>
- <dependency>
- <groupId>org.keycloak.subsystem</groupId>
- <artifactId>keycloak-server</artifactId>
- <type>war</type>
- <version>${project.version}</version>
- </dependency>
</dependencies>
<build>
@@ -123,10 +114,9 @@
<artifactItem>
<groupId>org.keycloak.subsystem</groupId>
<artifactId>keycloak-server</artifactId>
- <version>${project.version}</version>
<type>war</type>
<overWrite>true</overWrite>
- <outputDirectory>${project.build.directory}/${project.build.finalName}/modules/system/layers/base/org/keycloak/keycloak-server-subsystem/main/auth-server</outputDirectory>
+ <outputDirectory>${project.build.directory}/${project.build.finalName}/modules/system/layers/base/org/keycloak/keycloak-server-subsystem/main/server-war</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/de/idyl/winzipaes/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/de/idyl/winzipaes/main/module.xml
index 10f1103..14d7dff 100644
--- a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/de/idyl/winzipaes/main/module.xml
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/de/idyl/winzipaes/main/module.xml
@@ -4,7 +4,7 @@
<module xmlns="urn:jboss:module:1.1" name="de.idyl.winzipaes">
<resources>
- <!-- Insert resources here -->
+ <artifact name="${de.idyl:winzipaes}"/>
</resources>
<dependencies>
<module name="javax.api"/>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-server-subsystem/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-server-subsystem/main/module.xml
index 5233767..646c6d6 100644
--- a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-server-subsystem/main/module.xml
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-server-subsystem/main/module.xml
@@ -25,28 +25,14 @@
<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-server-subsystem">
<properties>
<property name="keycloak-version" value="${project.version}"/>
- <property name="auth-server-exploded" value="false"/>
+ <property name="server-war-exploded" value="false"/>
</properties>
<resources>
<resource-root path="."/>
- <artifact name="${org.keycloak:keycloak-wildfly-server-subsystem}"/>
</resources>
<dependencies>
- <module name="javax.api"/>
- <module name="org.jboss.staxmapper"/>
- <module name="org.jboss.as.controller"/>
- <module name="org.jboss.as.ee"/>
- <module name="org.jboss.as.server"/>
- <module name="org.jboss.modules"/>
- <module name="org.jboss.msc"/>
- <module name="org.jboss.logging"/>
- <module name="org.jboss.vfs"/>
- <module name="org.jboss.as.web-common" optional="true"/>
- <module name="org.jboss.as.web" optional="true"/>
- <module name="org.jboss.as.version" optional="true"/>
- <module name="org.keycloak.keycloak-wildfly-adapter" optional="true"/>
- <module name="org.jboss.metadata"/>
+ <module name="org.keycloak.keycloak-wf9-server-subsystem" services="export" export="true"/>
</dependencies>
</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-wf9-server-subsystem/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-wf9-server-subsystem/main/module.xml
new file mode 100644
index 0000000..61d3858
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-wf9-server-subsystem/main/module.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ~ JBoss, Home of Professional Open Source.
+ ~ Copyright 2014, 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.
+ -->
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-wf9-server-subsystem">
+ <properties>
+ <property name="keycloak-version" value="${project.version}"/>
+ <property name="server-war-exploded" value="false"/>
+ </properties>
+
+ <resources>
+ <resource-root path="."/>
+ <artifact name="${org.keycloak:keycloak-wf9-server-subsystem}"/>
+ </resources>
+
+ <dependencies>
+ <module name="javax.api"/>
+ <module name="org.jboss.staxmapper"/>
+ <module name="org.jboss.as.controller"/>
+ <module name="org.jboss.as.ee"/>
+ <module name="org.jboss.as.server"/>
+ <module name="org.jboss.modules"/>
+ <module name="org.jboss.msc"/>
+ <module name="org.jboss.logging"/>
+ <module name="org.jboss.vfs"/>
+ <module name="org.jboss.as.web-common" optional="true"/>
+ <module name="org.jboss.as.web" optional="true"/>
+ <module name="org.jboss.as.version" optional="true"/>
+ <module name="org.keycloak.keycloak-wildfly-adapter" optional="true"/>
+ <module name="org.jboss.metadata"/>
+ </dependencies>
+</module>
distribution/pom.xml 7(+3 -4)
diff --git a/distribution/pom.xml b/distribution/pom.xml
index 3b7a66f..ea3a726 100755
--- a/distribution/pom.xml
+++ b/distribution/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@@ -28,13 +28,12 @@
<modules>
<module>adapters</module>
- <!--<module>demo-dist</module>-->
+ <module>demo-dist</module>
<module>docs-dist</module>
<module>examples-dist</module>
- <module>modules</module>
<module>proxy-dist</module>
<module>server-dist</module>
- <!--<module>server-overlay</module>-->
+ <module>server-overlay</module>
<module>src-dist</module>
<module>subsystem-war</module>
<module>feature-packs</module>
distribution/proxy-dist/pom.xml 2(+1 -1)
diff --git a/distribution/proxy-dist/pom.xml b/distribution/proxy-dist/pom.xml
index 02b179a..4aa5555 100755
--- a/distribution/proxy-dist/pom.xml
+++ b/distribution/proxy-dist/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
distribution/server-dist/pom.xml 2(+1 -1)
diff --git a/distribution/server-dist/pom.xml b/distribution/server-dist/pom.xml
index 428b122..be3ab5b 100755
--- a/distribution/server-dist/pom.xml
+++ b/distribution/server-dist/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
diff --git a/distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/javax/ws/rs/api/2.0/module.xml b/distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/javax/ws/rs/api/2.0/module.xml
new file mode 100644
index 0000000..e972564
--- /dev/null
+++ b/distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/javax/ws/rs/api/2.0/module.xml
@@ -0,0 +1,12 @@
+<module xmlns="urn:jboss:module:1.3" name="javax.ws.rs.api">
+ <resources>
+ <resource-root path="jboss-jaxrs-api_2.0_spec-1.0.0.Final.jar"/>
+ <!-- Insert resources here -->
+ </resources>
+
+ <dependencies>
+ <module name="org.jboss.resteasy.resteasy-jaxrs" services="export"/>
+ <module name="javax.xml.bind.api" />
+ <module name="javax.api" />
+ </dependencies>
+</module>
\ No newline at end of file
diff --git a/distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/bouncycastle/main/module.xml b/distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/bouncycastle/main/module.xml
new file mode 100644
index 0000000..d8fcf47
--- /dev/null
+++ b/distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/bouncycastle/main/module.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<module xmlns="urn:jboss:module:1.1" name="org.bouncycastle">
+ <resources>
+ <!-- Insert resources here -->
+ </resources>
+ <dependencies>
+ <module name="javax.api"/>
+ </dependencies>
+</module>
\ No newline at end of file
diff --git a/distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-server-subsystem/main/module.xml b/distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-server-subsystem/main/module.xml
new file mode 100755
index 0000000..4326de4
--- /dev/null
+++ b/distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/org/keycloak/keycloak-server-subsystem/main/module.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ~ JBoss, Home of Professional Open Source.
+ ~ Copyright 2014, 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.
+ -->
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-server-subsystem">
+ <properties>
+ <property name="keycloak-version" value="${project.version}"/>
+ <property name="server-exploded" value="false"/>
+ </properties>
+
+ <resources>
+ <resource-root path="."/>
+ <!-- Insert resources here -->
+ </resources>
+
+ <dependencies>
+ <module name="org.keycloak.keycloak-as7-server-subsystem" services="export" export="true"/>
+ </dependencies>
+</module>
diff --git a/distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/sun/jdk/jgss/main/module.xml b/distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/sun/jdk/jgss/main/module.xml
new file mode 100644
index 0000000..6df03ff
--- /dev/null
+++ b/distribution/server-overlay/eap6/eap6-server-modules/src/main/resources/modules/sun/jdk/jgss/main/module.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="sun.jdk.jgss">
+ <resources>
+ <!-- Insert resources here -->
+ </resources>
+ <dependencies>
+ <system export="true">
+ <paths>
+ <path name="sun/security/jgss" />
+ <path name="sun/security/jgss/spi" />
+ <path name="sun/security/jgss/krb5" />
+ </paths>
+ </system>
+ </dependencies>
+
+</module>
\ No newline at end of file
diff --git a/distribution/server-overlay/eap6/eap6-server-overlay/pom.xml b/distribution/server-overlay/eap6/eap6-server-overlay/pom.xml
new file mode 100755
index 0000000..2e4907f
--- /dev/null
+++ b/distribution/server-overlay/eap6/eap6-server-overlay/pom.xml
@@ -0,0 +1,104 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>keycloak-parent</artifactId>
+ <groupId>org.keycloak</groupId>
+ <version>1.4.0.Final-SNAPSHOT</version>
+ <relativePath>../../../../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>keycloak-eap6-server-overlay</artifactId>
+ <packaging>pom</packaging>
+ <name>Keycloak EAP 6 Server Overlay Distribution</name>
+ <description/>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.keycloak</groupId>
+ <artifactId>keycloak-eap6-server-modules</artifactId>
+ <type>zip</type>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <finalName>keycloak-overlay-eap6-${project.version}</finalName>
+
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>unpack-jboss-modules</id>
+ <phase>prepare-package</phase>
+ <goals>
+ <goal>unpack</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+ <groupId>org.keycloak</groupId>
+ <artifactId>keycloak-eap6-server-modules</artifactId>
+ <type>zip</type>
+ <outputDirectory>${project.build.directory}/unpacked/modules</outputDirectory>
+ </artifactItem>
+ </artifactItems>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>xml-maven-plugin</artifactId>
+ <version>1.0</version>
+ <executions>
+ <execution>
+ <id>generate-resources</id>
+ <phase>package</phase>
+ <goals>
+ <goal>transform</goal>
+ </goals>
+ <configuration>
+ <transformationSets>
+ <transformationSet>
+ <dir>src/main</dir>
+ <stylesheet>src/main/xslt/standalone.xsl</stylesheet>
+ <includes>
+ <include>standalone.xml</include>
+ </includes>
+ <outputDir>${project.build.directory}</outputDir>
+ </transformationSet>
+ </transformationSets>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>assemble</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <configuration>
+ <descriptors>
+ <descriptor>assembly.xml</descriptor>
+ </descriptors>
+ <recompressZippedFiles>true</recompressZippedFiles>
+ <finalName>${project.build.finalName}</finalName>
+ <appendAssemblyId>false</appendAssemblyId>
+ <outputDirectory>${project.build.directory}</outputDirectory>
+ <workDirectory>${project.build.directory}/assembly/work</workDirectory>
+ <tarLongFileMode>gnu</tarLongFileMode>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/distribution/server-overlay/eap6/eap6-server-overlay/src/main/standalone.xml b/distribution/server-overlay/eap6/eap6-server-overlay/src/main/standalone.xml
new file mode 100644
index 0000000..5835618
--- /dev/null
+++ b/distribution/server-overlay/eap6/eap6-server-overlay/src/main/standalone.xml
@@ -0,0 +1,341 @@
+<?xml version='1.0' encoding='UTF-8'?>
+
+<server xmlns="urn:jboss:domain:1.7">
+ <extensions>
+ <extension module="org.jboss.as.clustering.infinispan"/>
+ <extension module="org.jboss.as.connector"/>
+ <extension module="org.jboss.as.deployment-scanner"/>
+ <extension module="org.jboss.as.ee"/>
+ <extension module="org.jboss.as.ejb3"/>
+ <extension module="org.jboss.as.jaxrs"/>
+ <extension module="org.jboss.as.jdr"/>
+ <extension module="org.jboss.as.jmx"/>
+ <extension module="org.jboss.as.jpa"/>
+ <extension module="org.jboss.as.jsf"/>
+ <extension module="org.jboss.as.logging"/>
+ <extension module="org.jboss.as.mail"/>
+ <extension module="org.jboss.as.naming"/>
+ <extension module="org.jboss.as.pojo"/>
+ <extension module="org.jboss.as.remoting"/>
+ <extension module="org.jboss.as.sar"/>
+ <extension module="org.jboss.as.security"/>
+ <extension module="org.jboss.as.threads"/>
+ <extension module="org.jboss.as.transactions"/>
+ <extension module="org.jboss.as.web"/>
+ <extension module="org.jboss.as.webservices"/>
+ <extension module="org.jboss.as.weld"/>
+ </extensions>
+ <management>
+ <security-realms>
+ <security-realm name="ManagementRealm">
+ <authentication>
+ <local default-user="$local" skip-group-loading="true"/>
+ <properties path="mgmt-users.properties" relative-to="jboss.server.config.dir"/>
+ </authentication>
+ <authorization map-groups-to-roles="false">
+ <properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
+ </authorization>
+ </security-realm>
+ <security-realm name="ApplicationRealm">
+ <authentication>
+ <local default-user="$local" allowed-users="*" skip-group-loading="true"/>
+ <properties path="application-users.properties" relative-to="jboss.server.config.dir"/>
+ </authentication>
+ <authorization>
+ <properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
+ </authorization>
+ </security-realm>
+ </security-realms>
+ <audit-log>
+ <formatters>
+ <json-formatter name="json-formatter"/>
+ </formatters>
+ <handlers>
+ <file-handler name="file" formatter="json-formatter" relative-to="jboss.server.data.dir" path="audit-log.log"/>
+ </handlers>
+ <logger log-boot="true" log-read-only="false" enabled="false">
+ <handlers>
+ <handler name="file"/>
+ </handlers>
+ </logger>
+ </audit-log>
+ <management-interfaces>
+ <native-interface security-realm="ManagementRealm">
+ <socket-binding native="management-native"/>
+ </native-interface>
+ <http-interface security-realm="ManagementRealm">
+ <socket-binding http="management-http"/>
+ </http-interface>
+ </management-interfaces>
+ <access-control provider="simple">
+ <role-mapping>
+ <role name="SuperUser">
+ <include>
+ <user name="$local"/>
+ </include>
+ </role>
+ </role-mapping>
+ </access-control>
+ </management>
+ <profile>
+ <subsystem xmlns="urn:jboss:domain:logging:1.5">
+ <console-handler name="CONSOLE">
+ <level name="INFO"/>
+ <formatter>
+ <named-formatter name="COLOR-PATTERN"/>
+ </formatter>
+ </console-handler>
+ <periodic-rotating-file-handler name="FILE" autoflush="true">
+ <formatter>
+ <named-formatter name="PATTERN"/>
+ </formatter>
+ <file relative-to="jboss.server.log.dir" path="server.log"/>
+ <suffix value=".yyyy-MM-dd"/>
+ <append value="true"/>
+ </periodic-rotating-file-handler>
+ <logger category="com.arjuna">
+ <level name="WARN"/>
+ </logger>
+ <logger category="org.apache.tomcat.util.modeler">
+ <level name="WARN"/>
+ </logger>
+ <logger category="org.jboss.as.config">
+ <level name="DEBUG"/>
+ </logger>
+ <logger category="sun.rmi">
+ <level name="WARN"/>
+ </logger>
+ <logger category="jacorb">
+ <level name="WARN"/>
+ </logger>
+ <logger category="jacorb.config">
+ <level name="ERROR"/>
+ </logger>
+ <root-logger>
+ <level name="INFO"/>
+ <handlers>
+ <handler name="CONSOLE"/>
+ <handler name="FILE"/>
+ </handlers>
+ </root-logger>
+ <formatter name="PATTERN">
+ <pattern-formatter pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>
+ </formatter>
+ <formatter name="COLOR-PATTERN">
+ <pattern-formatter pattern="%K{level}%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>
+ </formatter>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:datasources:1.2">
+ <datasources>
+ <datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true">
+ <connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url>
+ <driver>h2</driver>
+ <security>
+ <user-name>sa</user-name>
+ <password>sa</password>
+ </security>
+ </datasource>
+ <drivers>
+ <driver name="h2" module="com.h2database.h2">
+ <xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
+ </driver>
+ </drivers>
+ </datasources>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:deployment-scanner:1.1">
+ <deployment-scanner path="deployments" relative-to="jboss.server.base.dir" scan-interval="5000"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:ee:1.2">
+ <spec-descriptor-property-replacement>false</spec-descriptor-property-replacement>
+ <jboss-descriptor-property-replacement>true</jboss-descriptor-property-replacement>
+ <annotation-property-replacement>false</annotation-property-replacement>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:ejb3:1.5">
+ <session-bean>
+ <stateless>
+ <bean-instance-pool-ref pool-name="slsb-strict-max-pool"/>
+ </stateless>
+ <stateful default-access-timeout="5000" cache-ref="simple"/>
+ <singleton default-access-timeout="5000"/>
+ </session-bean>
+ <pools>
+ <bean-instance-pools>
+ <strict-max-pool name="slsb-strict-max-pool" max-pool-size="20" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
+ <strict-max-pool name="mdb-strict-max-pool" max-pool-size="20" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
+ </bean-instance-pools>
+ </pools>
+ <caches>
+ <cache name="simple" aliases="NoPassivationCache"/>
+ <cache name="passivating" passivation-store-ref="file" aliases="SimpleStatefulCache"/>
+ </caches>
+ <passivation-stores>
+ <file-passivation-store name="file"/>
+ </passivation-stores>
+ <async thread-pool-name="default"/>
+ <timer-service thread-pool-name="default" default-data-store="default-file-store">
+ <data-stores>
+ <file-data-store name="default-file-store" path="timer-service-data" relative-to="jboss.server.data.dir"/>
+ </data-stores>
+ </timer-service>
+ <remote connector-ref="remoting-connector" thread-pool-name="default"/>
+ <thread-pools>
+ <thread-pool name="default">
+ <max-threads count="10"/>
+ <keepalive-time time="100" unit="milliseconds"/>
+ </thread-pool>
+ </thread-pools>
+ <default-security-domain value="other"/>
+ <default-missing-method-permissions-deny-access value="true"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:infinispan:1.5">
+ <cache-container name="web" aliases="standard-session-cache" default-cache="local-web" module="org.jboss.as.clustering.web.infinispan">
+ <local-cache name="local-web" batching="true">
+ <file-store passivation="false" purge="false"/>
+ </local-cache>
+ </cache-container>
+ <cache-container name="hibernate" default-cache="local-query" module="org.jboss.as.jpa.hibernate:4">
+ <local-cache name="entity">
+ <transaction mode="NON_XA"/>
+ <eviction strategy="LRU" max-entries="10000"/>
+ <expiration max-idle="100000"/>
+ </local-cache>
+ <local-cache name="local-query">
+ <transaction mode="NONE"/>
+ <eviction strategy="LRU" max-entries="10000"/>
+ <expiration max-idle="100000"/>
+ </local-cache>
+ <local-cache name="timestamps">
+ <transaction mode="NONE"/>
+ <eviction strategy="NONE"/>
+ </local-cache>
+ </cache-container>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:jaxrs:1.0"/>
+ <subsystem xmlns="urn:jboss:domain:jca:1.1">
+ <archive-validation enabled="true" fail-on-error="true" fail-on-warn="false"/>
+ <bean-validation enabled="true"/>
+ <default-workmanager>
+ <short-running-threads>
+ <core-threads count="50"/>
+ <queue-length count="50"/>
+ <max-threads count="50"/>
+ <keepalive-time time="10" unit="seconds"/>
+ </short-running-threads>
+ <long-running-threads>
+ <core-threads count="50"/>
+ <queue-length count="50"/>
+ <max-threads count="50"/>
+ <keepalive-time time="10" unit="seconds"/>
+ </long-running-threads>
+ </default-workmanager>
+ <cached-connection-manager/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:jdr:1.0"/>
+ <subsystem xmlns="urn:jboss:domain:jmx:1.3">
+ <expose-resolved-model/>
+ <expose-expression-model/>
+ <remoting-connector/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:jpa:1.1">
+ <jpa default-datasource="" default-extended-persistence-inheritance="DEEP"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:jsf:1.0"/>
+ <subsystem xmlns="urn:jboss:domain:mail:1.2">
+ <mail-session name="default" jndi-name="java:jboss/mail/Default">
+ <smtp-server outbound-socket-binding-ref="mail-smtp"/>
+ </mail-session>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:naming:1.4">
+ <remote-naming/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:pojo:1.0"/>
+ <subsystem xmlns="urn:jboss:domain:remoting:1.2">
+ <connector name="remoting-connector" socket-binding="remoting" security-realm="ApplicationRealm"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:resource-adapters:1.1"/>
+ <subsystem xmlns="urn:jboss:domain:sar:1.0"/>
+ <subsystem xmlns="urn:jboss:domain:security:1.2">
+ <security-domains>
+ <security-domain name="other" cache-type="default">
+ <authentication>
+ <login-module code="Remoting" flag="optional">
+ <module-option name="password-stacking" value="useFirstPass"/>
+ </login-module>
+ <login-module code="RealmDirect" flag="required">
+ <module-option name="password-stacking" value="useFirstPass"/>
+ </login-module>
+ </authentication>
+ </security-domain>
+ <security-domain name="jboss-web-policy" cache-type="default">
+ <authorization>
+ <policy-module code="Delegating" flag="required"/>
+ </authorization>
+ </security-domain>
+ <security-domain name="jboss-ejb-policy" cache-type="default">
+ <authorization>
+ <policy-module code="Delegating" flag="required"/>
+ </authorization>
+ </security-domain>
+ </security-domains>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:threads:1.1"/>
+ <subsystem xmlns="urn:jboss:domain:transactions:1.5">
+ <core-environment>
+ <process-id>
+ <uuid/>
+ </process-id>
+ </core-environment>
+ <recovery-environment socket-binding="txn-recovery-environment" status-socket-binding="txn-status-manager"/>
+ <coordinator-environment default-timeout="300"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:web:2.2" default-virtual-server="default-host" native="false">
+ <connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http"/>
+ <virtual-server name="default-host" enable-welcome-root="true">
+ <alias name="localhost"/>
+ <alias name="example.com"/>
+ </virtual-server>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:webservices:1.2">
+ <modify-wsdl-address>true</modify-wsdl-address>
+ <wsdl-host>${jboss.bind.address:127.0.0.1}</wsdl-host>
+ <endpoint-config name="Standard-Endpoint-Config"/>
+ <endpoint-config name="Recording-Endpoint-Config">
+ <pre-handler-chain name="recording-handlers" protocol-bindings="##SOAP11_HTTP ##SOAP11_HTTP_MTOM ##SOAP12_HTTP ##SOAP12_HTTP_MTOM">
+ <handler name="RecordingHandler" class="org.jboss.ws.common.invocation.RecordingServerHandler"/>
+ </pre-handler-chain>
+ </endpoint-config>
+ <client-config name="Standard-Client-Config"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:weld:1.0"/>
+ </profile>
+ <interfaces>
+ <interface name="management">
+ <inet-address value="${jboss.bind.address.management:127.0.0.1}"/>
+ </interface>
+ <interface name="public">
+ <inet-address value="${jboss.bind.address:127.0.0.1}"/>
+ </interface>
+ <!-- TODO - only show this if the jacorb subsystem is added -->
+ <interface name="unsecure">
+ <!--
+ ~ Used for IIOP sockets in the standard configuration.
+ ~ To secure JacORB you need to setup SSL
+ -->
+ <inet-address value="${jboss.bind.address.unsecure:127.0.0.1}"/>
+ </interface>
+ </interfaces>
+ <socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
+ <socket-binding name="management-native" interface="management" port="${jboss.management.native.port:9999}"/>
+ <socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/>
+ <socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9443}"/>
+ <socket-binding name="ajp" port="8009"/>
+ <socket-binding name="http" port="8080"/>
+ <socket-binding name="https" port="8443"/>
+ <socket-binding name="remoting" port="4447"/>
+ <socket-binding name="txn-recovery-environment" port="4712"/>
+ <socket-binding name="txn-status-manager" port="4713"/>
+ <outbound-socket-binding name="mail-smtp">
+ <remote-destination host="localhost" port="25"/>
+ </outbound-socket-binding>
+ </socket-binding-group>
+</server>
\ No newline at end of file
distribution/server-overlay/eap6/pom.xml 21(+21 -0)
diff --git a/distribution/server-overlay/eap6/pom.xml b/distribution/server-overlay/eap6/pom.xml
new file mode 100755
index 0000000..2504fce
--- /dev/null
+++ b/distribution/server-overlay/eap6/pom.xml
@@ -0,0 +1,21 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>keycloak-parent</artifactId>
+ <groupId>org.keycloak</groupId>
+ <version>1.4.0.Final-SNAPSHOT</version>
+ <relativePath>../../../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>keycloak-eap6-server-overlay-parent</artifactId>
+ <packaging>pom</packaging>
+ <name>Keycloak EAP 6 Server Overlay</name>
+ <description/>
+
+
+ <modules>
+ <module>eap6-server-modules</module>
+ <module>eap6-server-overlay</module>
+ </modules>
+</project>
distribution/server-overlay/pom.xml 144(+21 -123)
diff --git a/distribution/server-overlay/pom.xml b/distribution/server-overlay/pom.xml
index a066b2c..f05e486 100755
--- a/distribution/server-overlay/pom.xml
+++ b/distribution/server-overlay/pom.xml
@@ -1,123 +1,21 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <artifactId>keycloak-parent</artifactId>
- <groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
- <relativePath>../../pom.xml</relativePath>
- </parent>
-
- <artifactId>keycloak-server-overlay</artifactId>
- <packaging>pom</packaging>
- <name>Keycloak Server Overlay</name>
- <description/>
-
- <dependencies>
- <dependency>
- <groupId>org.keycloak</groupId>
- <artifactId>keycloak-jboss-modules</artifactId>
- <type>zip</type>
- </dependency>
- <dependency>
- <groupId>org.wildfly</groupId>
- <artifactId>wildfly-dist</artifactId>
- <type>zip</type>
- </dependency>
- </dependencies>
-
- <build>
- <finalName>keycloak-overlay-${project.version}</finalName>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-dependency-plugin</artifactId>
- <executions>
- <execution>
- <id>unpack-standalone-xml</id>
- <phase>prepare-package</phase>
- <goals>
- <goal>unpack</goal>
- </goals>
- <configuration>
- <artifactItems>
- <artifactItem>
- <groupId>org.wildfly</groupId>
- <artifactId>wildfly-dist</artifactId>
- <type>zip</type>
- <outputDirectory>${project.build.directory}/unpacked</outputDirectory>
- </artifactItem>
- </artifactItems>
- <includes>*/standalone/configuration/standalone.xml</includes>
- </configuration>
- </execution>
- <execution>
- <id>unpack-module</id>
- <phase>prepare-package</phase>
- <goals>
- <goal>unpack</goal>
- </goals>
- <configuration>
- <artifactItems>
- <artifactItem>
- <groupId>org.keycloak</groupId>
- <artifactId>keycloak-jboss-modules</artifactId>
- <type>zip</type>
- <outputDirectory>${project.build.directory}/unpacked/modules</outputDirectory>
- </artifactItem>
- </artifactItems>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>xml-maven-plugin</artifactId>
- <version>1.0</version>
- <executions>
- <execution>
- <id>generate-resources</id>
- <phase>package</phase>
- <goals>
- <goal>transform</goal>
- </goals>
- <configuration>
- <transformationSets>
- <transformationSet>
- <dir>${project.build.directory}/unpacked/wildfly-${wildfly.version}/standalone/configuration</dir>
- <stylesheet>src/main/xslt/standalone.xsl</stylesheet>
- <includes>
- <include>standalone.xml</include>
- </includes>
- <outputDir>${project.build.directory}/unpacked/wildfly-${wildfly.version}/standalone/configuration</outputDir>
- </transformationSet>
- </transformationSets>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <artifactId>maven-assembly-plugin</artifactId>
- <executions>
- <execution>
- <id>assemble</id>
- <phase>package</phase>
- <goals>
- <goal>single</goal>
- </goals>
- <configuration>
- <descriptors>
- <descriptor>assembly.xml</descriptor>
- </descriptors>
- <outputDirectory>target</outputDirectory>
- <workDirectory>target/assembly/work</workDirectory>
- <appendAssemblyId>false</appendAssemblyId>
- <tarLongFileMode>gnu</tarLongFileMode>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-
-</project>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>keycloak-parent</artifactId>
+ <groupId>org.keycloak</groupId>
+ <version>1.4.0.Final-SNAPSHOT</version>
+ <relativePath>../../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>keycloak-server-overlay</artifactId>
+ <packaging>pom</packaging>
+ <name>Keycloak Server Overlay Distributions</name>
+ <description/>
+
+
+ <modules>
+ <module>wf9-server-overlay</module>
+ <module>eap6</module>
+ </modules>
+</project>
diff --git a/distribution/server-overlay/wf9-server-overlay/assembly.xml b/distribution/server-overlay/wf9-server-overlay/assembly.xml
new file mode 100755
index 0000000..4d87e69
--- /dev/null
+++ b/distribution/server-overlay/wf9-server-overlay/assembly.xml
@@ -0,0 +1,67 @@
+<assembly>
+ <id>server-dist</id>
+
+ <formats>
+ <format>zip</format>
+ <format>tar.gz</format>
+ </formats>
+
+ <includeBaseDirectory>false</includeBaseDirectory>
+
+ <fileSets>
+ <fileSet>
+ <directory>${project.build.directory}/unpacked/keycloak-${project.version}/modules/system/layers/base</directory>
+ <outputDirectory>modules/system/layers/base</outputDirectory>
+ <includes>
+ <include>com/google/zxing/**</include>
+ <include>de/idyl/winzipaes/**</include>
+ <include>net/iharder/**</include>
+ <include>org/freemarker/**</include>
+ <include>org/keycloak/**</include>
+ <include>org/liquibase/**</include>
+ <include>org/mongodb/**</include>
+ <include>org/twitter4j/**</include>
+ <include>sun/jdk/jgss/**</include>
+ </includes>
+ </fileSet>
+ <fileSet>
+ <directory>${project.build.directory}/unpacked/keycloak-${project.version}/content</directory>
+ <outputDirectory></outputDirectory>
+ </fileSet>
+ <fileSet>
+ <directory>${project.build.directory}/unpacked/keycloak-${project.version}/standalone/configuration/themes</directory>
+ <outputDirectory>standalone/configuration/themes</outputDirectory>
+ <includes>
+ <include>**/**</include>
+ </includes>
+ </fileSet>
+ <fileSet>
+ <directory>${project.build.directory}/unpacked/keycloak-${project.version}/standalone/configuration/providers</directory>
+ <outputDirectory>standalone/configuration/providers</outputDirectory>
+ <includes>
+ <include>**/**</include>
+ </includes>
+ </fileSet>
+ <fileSet>
+ <directory>../../</directory>
+ <includes>
+ <include>License.html</include>
+ </includes>
+ <outputDirectory></outputDirectory>
+ </fileSet>
+
+ </fileSets>
+
+ <files>
+ <file>
+ <source>${project.build.directory}/unpacked/keycloak-${project.version}/standalone/configuration/standalone.xml</source>
+ <outputDirectory>standalone/configuration</outputDirectory>
+ <destName>standalone-keycloak.xml</destName>
+ </file>
+ <file>
+ <source>${project.build.directory}/unpacked/keycloak-${project.version}/standalone/configuration/keycloak-server.json</source>
+ <outputDirectory>standalone/configuration</outputDirectory>
+ </file>
+ </files>
+
+</assembly>
diff --git a/distribution/server-overlay/wf9-server-overlay/pom.xml b/distribution/server-overlay/wf9-server-overlay/pom.xml
new file mode 100755
index 0000000..5219ebc
--- /dev/null
+++ b/distribution/server-overlay/wf9-server-overlay/pom.xml
@@ -0,0 +1,78 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>keycloak-parent</artifactId>
+ <groupId>org.keycloak</groupId>
+ <version>1.4.0.Final-SNAPSHOT</version>
+ <relativePath>../../../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>keycloak-wf9-server-overlay</artifactId>
+ <packaging>pom</packaging>
+ <name>Keycloak Wildfly 9 Server Overlay Distribution</name>
+ <description/>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.keycloak</groupId>
+ <artifactId>keycloak-server-dist</artifactId>
+ <type>zip</type>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <finalName>keycloak-overlay-${project.version}</finalName>
+
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>unpack-server-dist</id>
+ <phase>prepare-package</phase>
+ <goals>
+ <goal>unpack</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+ <groupId>org.keycloak</groupId>
+ <artifactId>keycloak-server-dist</artifactId>
+ <type>zip</type>
+ <outputDirectory>${project.build.directory}/unpacked</outputDirectory>
+ </artifactItem>
+ </artifactItems>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>assemble</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <configuration>
+ <descriptors>
+ <descriptor>assembly.xml</descriptor>
+ </descriptors>
+ <recompressZippedFiles>true</recompressZippedFiles>
+ <finalName>${project.build.finalName}</finalName>
+ <appendAssemblyId>false</appendAssemblyId>
+ <outputDirectory>${project.build.directory}</outputDirectory>
+ <workDirectory>${project.build.directory}/assembly/work</workDirectory>
+ <tarLongFileMode>gnu</tarLongFileMode>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
distribution/src-dist/pom.xml 2(+1 -1)
diff --git a/distribution/src-dist/pom.xml b/distribution/src-dist/pom.xml
index 14d63e3..028d156 100755
--- a/distribution/src-dist/pom.xml
+++ b/distribution/src-dist/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
distribution/subsystem-war/pom.xml 2(+1 -1)
diff --git a/distribution/subsystem-war/pom.xml b/distribution/subsystem-war/pom.xml
index f1ea3f6..4be6a11 100755
--- a/distribution/subsystem-war/pom.xml
+++ b/distribution/subsystem-war/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
docbook/pom.xml 2(+1 -1)
diff --git a/docbook/pom.xml b/docbook/pom.xml
index 009b220..f97e203 100755
--- a/docbook/pom.xml
+++ b/docbook/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
diff --git a/docbook/reference/en/en-US/master.xml b/docbook/reference/en/en-US/master.xml
index 218a1aa..d379ac8 100755
--- a/docbook/reference/en/en-US/master.xml
+++ b/docbook/reference/en/en-US/master.xml
@@ -35,6 +35,7 @@
<!ENTITY UserFederation SYSTEM "modules/user-federation.xml">
<!ENTITY Kerberos SYSTEM "modules/kerberos.xml">
<!ENTITY ExportImport SYSTEM "modules/export-import.xml">
+ <!ENTITY AdminRecovery SYSTEM "modules/admin-recovery.xml">
<!ENTITY ServerCache SYSTEM "modules/cache.xml">
<!ENTITY SecurityVulnerabilities SYSTEM "modules/security-vulnerabilities.xml">
<!ENTITY Clustering SYSTEM "modules/clustering.xml">
@@ -126,6 +127,7 @@ This one is short
&UserFederation;
&Kerberos;
&ExportImport;
+ &AdminRecovery;
&ServerCache;
&SAML;
&SecurityVulnerabilities;
diff --git a/docbook/reference/en/en-US/modules/admin-recovery.xml b/docbook/reference/en/en-US/modules/admin-recovery.xml
new file mode 100755
index 0000000..9412848
--- /dev/null
+++ b/docbook/reference/en/en-US/modules/admin-recovery.xml
@@ -0,0 +1,15 @@
+<chapter id="admin-recovery">
+ <title>Recovering the Master Admin User</title>
+ <para>
+ It is possible for the "admin" user in the master realm to become inoperable. This may be because it was
+ accidentally deleted, its role mappings were removed, or the password was simply forgotten.
+ </para>
+ <para>
+ To recover the master admin user, just start the server with the following system properties:
+ <programlisting><![CDATA[
+bin/standalone.sh -Dkeycloak.recover-admin=true -Dkeycloak.temp-admin-password=temppassword
+]]></programlisting>
+ Then you can log in to the master admin account with your temporary password. You will then be
+ prompted to immediately change this password.
+ </para>
+</chapter>
\ No newline at end of file
diff --git a/docbook/reference/en/en-US/modules/identity-broker.xml b/docbook/reference/en/en-US/modules/identity-broker.xml
index 75df2c7..2288ed7 100755
--- a/docbook/reference/en/en-US/modules/identity-broker.xml
+++ b/docbook/reference/en/en-US/modules/identity-broker.xml
@@ -1246,6 +1246,24 @@ keycloak.createLoginUrl({
the tool tips to see what each mapper can do for you.
</para>
</section>
+
+ <section>
+ <title>Mapping/Importing User profile data from Social Identity Provider</title>
+ <para>
+ You can import user profile data provided by social identity providers like Google, GitHub, LinkedIn, Stackoverflow and Facebook
+ into new Keycloak user created from given social accounts. After you configure a broker, you'll see a <literal>Mappers</literal>
+ button appear. Click on that and you'll get to the list of mappers that are assigned to this broker. There is a
+ <literal>Create</literal> button on this page. Clicking on this create button allows you to create a broker mapper.
+ "Attribute Importer" mapper allows you to define path in JSON user profile data provided by the provider to get value from.
+ You can use dot notation for nesting and square brackets to access fields in array by index. For example 'contact.address[0].country'.
+ Then you can define name of Keycloak's user profile attribute this value is stored into.
+ </para>
+ <para>
+ To investigate structure of user profile JSON data provided by social providers you can enable <literal>DEBUG</literal> level for
+ logger <literal>org.keycloak.social.user_profile_dump</literal> and login using given provider. Then you can find user profile
+ JSON structure in Keycloak log file.
+ </para>
+ </section>
<section>
<title>Examples</title>
diff --git a/docbook/reference/en/en-US/modules/jboss-adapter.xml b/docbook/reference/en/en-US/modules/jboss-adapter.xml
index c89d9b1..3995447 100755
--- a/docbook/reference/en/en-US/modules/jboss-adapter.xml
+++ b/docbook/reference/en/en-US/modules/jboss-adapter.xml
@@ -14,10 +14,17 @@
the Keycloak download site. They are also available as a maven artifact.
</para>
<para>
- Install on Wildfly:
+ Install on Wildfly 9:
<programlisting>
$ cd $WILDFLY_HOME
-$ unzip keycloak-wildfly-adapter-dist.zip
+$ unzip keycloak-wf9-adapter-dist.zip
+</programlisting>
+ </para>
+ <para>
+ Install on Wildfly 8:
+<programlisting>
+$ cd $WILDFLY_HOME
+$ unzip keycloak-wf8-adapter-dist.zip
</programlisting>
</para>
<para>
@@ -56,7 +63,6 @@ $ unzip keycloak-as7-adapter-dist.zip
</profile>
]]>
</programlisting>
-<note>For AS7, the extension module is org.keycloak.keycloak-as7-subsystem.</note>
</para>
<para>
Finally, you must specify a shared keycloak security domain.
diff --git a/docbook/reference/en/en-US/modules/MigrationFromOlderVersions.xml b/docbook/reference/en/en-US/modules/MigrationFromOlderVersions.xml
index dc8e440..f4fdec2 100755
--- a/docbook/reference/en/en-US/modules/MigrationFromOlderVersions.xml
+++ b/docbook/reference/en/en-US/modules/MigrationFromOlderVersions.xml
@@ -89,6 +89,40 @@
option to enable/disable for a realm is removed.
</para>
</simplesect>
+ <simplesect>
+ <title>Database changed</title>
+ <para>
+ There are again few database changes. Remember to backup your database prior to upgrading.
+ </para>
+ </simplesect>
+ <simplesect>
+ <title>UserFederationProvider changed</title>
+ <para>
+ There are few minor changes in UserFederationProvider interface. You may need to sync your implementation when upgrade
+ to newer version and upgrade few methods, which has changed signature. Changes are really minor, but were needed to improve performance of federation.
+ </para>
+ </simplesect>
+ <simplesect>
+ <title>WildFly 9.0.0.CR2</title>
+ <para>
+ Following on from the distribution changes that was done in the last release the standalone download
+ of Keycloak is now based on WildFly 9.0.0.CR2. This als affects the overlay which can only be deployed
+ to WildFly 9.0.0.CR2 or JBoss EAP 6.4.0.GA. WildFly 8.2.0.Final is no longer supported for the server.
+ </para>
+ </simplesect>
+ <simplesect>
+ <title>WildFly, JBoss EAP and JBoss AS7 adapters</title>
+ <para>
+ There are now 3 separate adapter downloads for WildFly, JBoss EAP and JBoss AS7:
+ <itemizedlist>
+ <listitem><literal>eap6</literal> - for JBoss EAP 6.x</listitem>
+ <listitem><literal>wf9</literal> - for WildFly 9.x</listitem>
+ <listitem><literal>wf8</literal> - for WildFly 8.x</listitem>
+ <listitem><literal>as7</literal> - for JBoss AS 7.x</listitem>
+ </itemizedlist>
+ Make sure you grab the correct one.
+ </para>
+ </simplesect>
</section>
<section>
<title>Migrating from 1.2.0.Beta1 to 1.2.0.RC1</title>
diff --git a/docbook/reference/en/en-US/modules/server-installation.xml b/docbook/reference/en/en-US/modules/server-installation.xml
index 9c321a2..214d88a 100755
--- a/docbook/reference/en/en-US/modules/server-installation.xml
+++ b/docbook/reference/en/en-US/modules/server-installation.xml
@@ -43,9 +43,9 @@
<section id="overlay_install">
- <title>Install on existing WildFly 8.2.0.Final</title>
+ <title>Install on existing WildFly 9.0.0.CR2</title>
<para>
- Keycloak can be installed into an existing WildFly 8.2.0.Final server. To do this download
+ Keycloak can be installed into an existing WildFly 9.0.0.CR2 server. To do this download
<literal>keycloak-overlay-&project.version;.zip</literal> or <literal>keycloak-overlay-&project.version;.tar.gz</literal>.
Once downloaded extract into the root directory of your WildFly installation. To start WildFly with Keycloak
run:
@@ -72,32 +72,9 @@
</para>
</section>
<section>
- <title>Install on existing EAP 6.4.0.GA</title>
+ <title>Install on existing JBoss EAP 6.4.0.GA</title>
<para>
- Keycloak can be installed into an existing EAP 6.4.0.GA server. To do this download
- <literal>keycloak-overlay-&project.version;.zip</literal> or <literal>keycloak-overlay-&project.version;.tar.gz</literal>.
- Once downloaded extract into the root directory of your EAP installation.
- </para>
- <para>
- To add Keycloak to the a EAP sever configurations (standalone.xml, standalone-ha.xml, etc.) open
- <literal>standalone/configuration/standalone-keycloak.xml</literal> and the configuration you want to add it
- to, for example <literal>standalone/configuration/standalone.xml</literal>. From <literal>standalone-keycloak.xml</literal>
- you need to copy 3 elements:
- <itemizedlist>
- <listitem><literal><extension module="org.keycloak.keycloak-subsystem"/></literal></listitem>
- <listitem><literal><datasource jndi-name="java:jboss/datasources/KeycloakDS" ...></literal></listitem>
- <listitem><literal><subsystem xmlns="urn:jboss:domain:keycloak:1.0" ...></literal></listitem>
- </itemizedlist>
- <note>
- <literal>standalone-keycloak.xml</literal> is aimed at WildFly and won't work with EAP so you need to
- copy the required configuration
- </note>
- </para>
- <para>
- Once the server is started log into the admin console at
- <ulink url="http://localhost:8080/auth/admin/index.html">http://localhost:8080/auth/admin/index.html</ulink>
- (username: <emphasis>admin</emphasis> and password: <emphasis>admin</emphasis>). Keycloak will then prompt you to
- enter in a new password.
+ Same procedure as JBoss EAP 6.4.0.GA, but download <literal>keycloak-overlay-eap6-&project.version;.zip</literal> or <literal>keycloak-overlay-eap6-&project.version;.tar.gz</literal>.
</para>
</section>
<section>
@@ -107,7 +84,7 @@
To install it first download <literal>keycloak-demo-&project.version;.zip</literal> or
<literal>keycloak-demo-&project.version;.tar.gz</literal>. Once downloaded extract it inside
<literal>keycloak-demo-&project.version;</literal> you'll find <literal>keycloak</literal> which contains
- a full WildFly 8.2.0.Final server with Keycloak Server and Adapters included. You'll also find <literal>docs</literal>
+ a full WildFly 9.0.0.CR2 server with Keycloak Server and Adapters included. You'll also find <literal>docs</literal>
and <literal>examples</literal> which contains everything you need to get started developing applications that use Keycloak.
</para>
<para>
diff --git a/docbook/reference/en/en-US/modules/user-federation.xml b/docbook/reference/en/en-US/modules/user-federation.xml
index a8e6c17..c8e9856 100755
--- a/docbook/reference/en/en-US/modules/user-federation.xml
+++ b/docbook/reference/en/en-US/modules/user-federation.xml
@@ -24,7 +24,8 @@
<section>
<title>LDAP and Active Directory Plugin</title>
<para>
- Keycloak comes with a built-in LDAP/AD plugin. Currently it is set up only to import username, email, first and last name.
+ Keycloak comes with a built-in LDAP/AD plugin. By default, it is set up only to import username, email, first and last name, but you are free
+ to configure <link linkend='ldap_mappers'>mappers</link> and add more attributes or delete default ones.
It supports password validation via LDAP/AD protocols and different user metadata synchronization modes. To configure
a federated LDAP store go to the admin console. Click on the <literal>Users</literal> menu option to get you
to the user management page. Then click on the <literal>Federation</literal> submenu option. When
@@ -41,7 +42,7 @@
<term>READONLY</term>
<listitem>
<para>
- Username, email, first and last name will be unchangable. Keycloak will show an error
+ Username, email, first and last name and other mapped attributes will be unchangeable. Keycloak will show an error
anytime anybody tries to update these fields. Also, password updates will not be supported.
</para>
</listitem>
@@ -50,7 +51,7 @@
<term>WRITABLE</term>
<listitem>
<para>
- Username, email, first and last name, and passwords can all be updated and will
+ Username, email, first and last name, other mapped attributes and passwords can all be updated and will
be synchronized automatically with your LDAP store.
</para>
</listitem>
@@ -158,6 +159,56 @@
</para>
<para>In admin console, you can trigger sync directly or you can enable periodic changed or full sync.</para>
</section>
+ <section id="ldap_mappers">
+ <title>LDAP/Federation mappers</title>
+ <para>
+ LDAP mappers are <literal>listeners</literal>, which are triggered by LDAP Federation provider at various points and provide
+ another extension point to LDAP integration. They are triggered during import LDAP user into Keycloak, registration Keycloak user back to LDAP or when querying LDAP user from Keycloak.
+ When you create LDAP Federation provider, Keycloak will automatically provide set of builtin <literal>mappers</literal> for this provider.
+ You are free to change this set and create new mapper or update/delete existing ones.
+ </para>
+ <para>
+ By default, we have those implementation of LDAP federation mapper:
+ <variablelist>
+ <varlistentry>
+ <term>User Attribute Mapper</term>
+ <listitem>
+ <para>
+ This allows to specify which LDAP attribute is mapped to which attribute of Keycloak User. So for example you can configure
+ that LDAP attribute <literal>mail</literal> is supposed to be mapped to the UserModel attribute <literal>email</literal> in Keycloak database.
+ For this mapper implementation, there is always one-to-one mapping (one LDAP attribute mapped to one Keycloak UserModel attribute)
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>FullName Mapper</term>
+ <listitem>
+ <para>
+ This allows to specify that fullname of user, which is saved in some LDAP attribute (usualy <literal>cn</literal> ) will be mapped to
+ <literal>firstName</literal> and <literal>lastname</literal> attributes of UserModel. Having <literal>cn</literal> to contain full name of user
+ is common case for some LDAP deployments.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Role Mapper</term>
+ <listitem>
+ <para>
+ This allows to configure role mappings from LDAP into Keycloak role mappings. One Role mapper can be used to map LDAP roles
+ (usually groups from particular branch of LDAP tree) into roles corresponding to either realm roles or client roles of specified client.
+ It's not a problem to configure more Role mappers for same LDAP provider. So for example you can specify that role mappings from groups under
+ <literal>ou=main,dc=example,dc=org</literal> will be mapped to realm role mappings and role mappings from
+ groups under <literal>ou=finance,dc=example,dc=org</literal> will be mapped to client role mappings of client <literal>finance</literal> .
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ <para>By default, there is set of User Attribute mappers to map basic UserModel attributes username, first name, lastname and email to corresponding LDAP attributes. You are free to extend this and provide
+ more attribute mappings (For example to street, postalCode etc), delete firstName/lastname mapper and put fullName mapper instead, add role mappers etc.
+ Admin console provides tooltips, which should help on how to configure corresponding mappers.
+ </para>
+ </section>
<section>
<title>Writing your own User Federation Provider</title>
<para>
events/api/pom.xml 2(+1 -1)
diff --git a/events/api/pom.xml b/events/api/pom.xml
index a70987f..f447d5f 100755
--- a/events/api/pom.xml
+++ b/events/api/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-events-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/events/api/src/main/java/org/keycloak/events/Details.java b/events/api/src/main/java/org/keycloak/events/Details.java
index 5564ced..73d98ff 100755
--- a/events/api/src/main/java/org/keycloak/events/Details.java
+++ b/events/api/src/main/java/org/keycloak/events/Details.java
@@ -28,4 +28,9 @@ public interface Details {
String CLIENT_SESSION_STATE = "client_session_state";
String CLIENT_SESSION_HOST = "client_session_host";
+ String CONSENT = "consent";
+ String CONSENT_VALUE_NO_CONSENT_REQUIRED = "no_consent_required"; // No consent is required by client
+ String CONSENT_VALUE_CONSENT_GRANTED = "consent_granted"; // Consent granted by user
+ String CONSENT_VALUE_PERSISTED_CONSENT = "persistent_consent"; // Persistent consent used (was already granted by user before)
+
}
events/email/pom.xml 2(+1 -1)
diff --git a/events/email/pom.xml b/events/email/pom.xml
index cd449b0..3972dc4 100755
--- a/events/email/pom.xml
+++ b/events/email/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-events-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
events/jboss-logging/pom.xml 2(+1 -1)
diff --git a/events/jboss-logging/pom.xml b/events/jboss-logging/pom.xml
index e575603..e11effb 100755
--- a/events/jboss-logging/pom.xml
+++ b/events/jboss-logging/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-events-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
events/jpa/pom.xml 2(+1 -1)
diff --git a/events/jpa/pom.xml b/events/jpa/pom.xml
index 260e76c..0a4736c 100755
--- a/events/jpa/pom.xml
+++ b/events/jpa/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-events-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
events/mongo/pom.xml 2(+1 -1)
diff --git a/events/mongo/pom.xml b/events/mongo/pom.xml
index 84de0f7..a686473 100755
--- a/events/mongo/pom.xml
+++ b/events/mongo/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-events-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
events/pom.xml 2(+1 -1)
diff --git a/events/pom.xml b/events/pom.xml
index f7d5a35..e956979 100755
--- a/events/pom.xml
+++ b/events/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
events/syslog/pom.xml 2(+1 -1)
diff --git a/events/syslog/pom.xml b/events/syslog/pom.xml
index cbe9b9c..585119c 100755
--- a/events/syslog/pom.xml
+++ b/events/syslog/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-events-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
examples/admin-client/pom.xml 2(+1 -1)
diff --git a/examples/admin-client/pom.xml b/examples/admin-client/pom.xml
index 78aea2d..cdeedce 100755
--- a/examples/admin-client/pom.xml
+++ b/examples/admin-client/pom.xml
@@ -5,7 +5,7 @@
<parent>
<artifactId>keycloak-examples-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<name>Keycloak Examples - Admin Client</name>
examples/basic-auth/pom.xml 2(+1 -1)
diff --git a/examples/basic-auth/pom.xml b/examples/basic-auth/pom.xml
index bd5c681..3f61feb 100755
--- a/examples/basic-auth/pom.xml
+++ b/examples/basic-auth/pom.xml
@@ -6,7 +6,7 @@
<parent>
<artifactId>keycloak-examples-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<name>Keycloak Examples - Basic Auth</name>
diff --git a/examples/broker/facebook-authentication/pom.xml b/examples/broker/facebook-authentication/pom.xml
index e28820c..0c36164 100755
--- a/examples/broker/facebook-authentication/pom.xml
+++ b/examples/broker/facebook-authentication/pom.xml
@@ -6,7 +6,7 @@
<parent>
<artifactId>keycloak-examples-broker-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<name>Keycloak Broker Examples - Facebook Authentication</name>
diff --git a/examples/broker/google-authentication/pom.xml b/examples/broker/google-authentication/pom.xml
index 3fea3c2..4086d96 100755
--- a/examples/broker/google-authentication/pom.xml
+++ b/examples/broker/google-authentication/pom.xml
@@ -6,7 +6,7 @@
<parent>
<artifactId>keycloak-examples-broker-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<name>Keycloak Broker Examples - Google Authentication</name>
examples/broker/pom.xml 2(+1 -1)
diff --git a/examples/broker/pom.xml b/examples/broker/pom.xml
index 7d328b4..193fa20 100755
--- a/examples/broker/pom.xml
+++ b/examples/broker/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-examples-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<name>Broker Examples</name>
diff --git a/examples/broker/saml-broker-authentication/pom.xml b/examples/broker/saml-broker-authentication/pom.xml
index bc12452..fff19ad 100755
--- a/examples/broker/saml-broker-authentication/pom.xml
+++ b/examples/broker/saml-broker-authentication/pom.xml
@@ -6,7 +6,7 @@
<parent>
<artifactId>keycloak-examples-broker-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<name>Keycloak Broker Examples - SAML Identity Provider Brokering</name>
diff --git a/examples/broker/twitter-authentication/pom.xml b/examples/broker/twitter-authentication/pom.xml
index 0896245..f2c2537 100755
--- a/examples/broker/twitter-authentication/pom.xml
+++ b/examples/broker/twitter-authentication/pom.xml
@@ -6,7 +6,7 @@
<parent>
<artifactId>keycloak-examples-broker-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<name>Keycloak Broker Examples - Twitter Authentication</name>
diff --git a/examples/cors/angular-product-app/pom.xml b/examples/cors/angular-product-app/pom.xml
index 4b69a88..237bf5a 100755
--- a/examples/cors/angular-product-app/pom.xml
+++ b/examples/cors/angular-product-app/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-examples-cors-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/examples/cors/database-service/pom.xml b/examples/cors/database-service/pom.xml
index 057e50b..ee5eb63 100755
--- a/examples/cors/database-service/pom.xml
+++ b/examples/cors/database-service/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-examples-cors-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
examples/cors/pom.xml 2(+1 -1)
diff --git a/examples/cors/pom.xml b/examples/cors/pom.xml
index fdfa514..a715cef 100755
--- a/examples/cors/pom.xml
+++ b/examples/cors/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-examples-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<name>Keycloak Examples - CORS</name>
diff --git a/examples/demo-template/admin-access-app/pom.xml b/examples/demo-template/admin-access-app/pom.xml
index 719c513..5894f73 100755
--- a/examples/demo-template/admin-access-app/pom.xml
+++ b/examples/demo-template/admin-access-app/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-examples-demo-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/examples/demo-template/angular-product-app/pom.xml b/examples/demo-template/angular-product-app/pom.xml
index 671283e..5376a09 100755
--- a/examples/demo-template/angular-product-app/pom.xml
+++ b/examples/demo-template/angular-product-app/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-examples-demo-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/examples/demo-template/customer-app/pom.xml b/examples/demo-template/customer-app/pom.xml
index 9bbe7a4..da6be3e 100755
--- a/examples/demo-template/customer-app/pom.xml
+++ b/examples/demo-template/customer-app/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-examples-demo-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/examples/demo-template/customer-app-cli/pom.xml b/examples/demo-template/customer-app-cli/pom.xml
index b5ac17a..30c481b 100755
--- a/examples/demo-template/customer-app-cli/pom.xml
+++ b/examples/demo-template/customer-app-cli/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-examples-demo-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/examples/demo-template/customer-app-js/pom.xml b/examples/demo-template/customer-app-js/pom.xml
index c64eac2..094d565 100755
--- a/examples/demo-template/customer-app-js/pom.xml
+++ b/examples/demo-template/customer-app-js/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-examples-demo-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/examples/demo-template/database-service/pom.xml b/examples/demo-template/database-service/pom.xml
index 3a09784..d80b10f 100755
--- a/examples/demo-template/database-service/pom.xml
+++ b/examples/demo-template/database-service/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-examples-demo-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/examples/demo-template/example-ear/pom.xml b/examples/demo-template/example-ear/pom.xml
index bfb6bff..6bb3400 100755
--- a/examples/demo-template/example-ear/pom.xml
+++ b/examples/demo-template/example-ear/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-examples-demo-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
examples/demo-template/pom.xml 2(+1 -1)
diff --git a/examples/demo-template/pom.xml b/examples/demo-template/pom.xml
index b002be1..20515f5 100755
--- a/examples/demo-template/pom.xml
+++ b/examples/demo-template/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-examples-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<name>Examples</name>
diff --git a/examples/demo-template/product-app/pom.xml b/examples/demo-template/product-app/pom.xml
index 675ff09..fca37fe 100755
--- a/examples/demo-template/product-app/pom.xml
+++ b/examples/demo-template/product-app/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-examples-demo-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/examples/demo-template/third-party/pom.xml b/examples/demo-template/third-party/pom.xml
index c2f23b3..6ec11d9 100755
--- a/examples/demo-template/third-party/pom.xml
+++ b/examples/demo-template/third-party/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-examples-demo-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/examples/demo-template/third-party-cdi/pom.xml b/examples/demo-template/third-party-cdi/pom.xml
index 7ac1d8d..d2f8da5 100755
--- a/examples/demo-template/third-party-cdi/pom.xml
+++ b/examples/demo-template/third-party-cdi/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-examples-demo-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
examples/fuse/camel/pom.xml 2(+1 -1)
diff --git a/examples/fuse/camel/pom.xml b/examples/fuse/camel/pom.xml
index fca482e..0719a0c 100755
--- a/examples/fuse/camel/pom.xml
+++ b/examples/fuse/camel/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-examples-fuse-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/examples/fuse/customer-app-fuse/pom.xml b/examples/fuse/customer-app-fuse/pom.xml
index de0c0d8..4583473 100755
--- a/examples/fuse/customer-app-fuse/pom.xml
+++ b/examples/fuse/customer-app-fuse/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-examples-fuse-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
examples/fuse/cxf-jaxrs/pom.xml 2(+1 -1)
diff --git a/examples/fuse/cxf-jaxrs/pom.xml b/examples/fuse/cxf-jaxrs/pom.xml
index b97346e..9ef099c 100755
--- a/examples/fuse/cxf-jaxrs/pom.xml
+++ b/examples/fuse/cxf-jaxrs/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-examples-fuse-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
examples/fuse/cxf-jaxws/pom.xml 2(+1 -1)
diff --git a/examples/fuse/cxf-jaxws/pom.xml b/examples/fuse/cxf-jaxws/pom.xml
index 594b519..aa23b5f 100755
--- a/examples/fuse/cxf-jaxws/pom.xml
+++ b/examples/fuse/cxf-jaxws/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-examples-fuse-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
examples/fuse/features/pom.xml 2(+1 -1)
diff --git a/examples/fuse/features/pom.xml b/examples/fuse/features/pom.xml
index d06af85..6f6465c 100755
--- a/examples/fuse/features/pom.xml
+++ b/examples/fuse/features/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-examples-fuse-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
examples/fuse/pom.xml 2(+1 -1)
diff --git a/examples/fuse/pom.xml b/examples/fuse/pom.xml
index f60ca2a..694d4b0 100755
--- a/examples/fuse/pom.xml
+++ b/examples/fuse/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-examples-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<name>Fuse examples</name>
diff --git a/examples/fuse/product-app-fuse/pom.xml b/examples/fuse/product-app-fuse/pom.xml
index 5231405..38bc235 100755
--- a/examples/fuse/product-app-fuse/pom.xml
+++ b/examples/fuse/product-app-fuse/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-examples-fuse-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
examples/js-console/pom.xml 2(+1 -1)
diff --git a/examples/js-console/pom.xml b/examples/js-console/pom.xml
index 7434c5c..02a2e32 100755
--- a/examples/js-console/pom.xml
+++ b/examples/js-console/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-examples-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
examples/kerberos/pom.xml 2(+1 -1)
diff --git a/examples/kerberos/pom.xml b/examples/kerberos/pom.xml
index 2ed56cd..ffe8259 100755
--- a/examples/kerberos/pom.xml
+++ b/examples/kerberos/pom.xml
@@ -5,7 +5,7 @@
<parent>
<artifactId>keycloak-examples-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<name>Keycloak Examples - Kerberos Credential Delegation</name>
examples/multi-tenant/pom.xml 2(+1 -1)
diff --git a/examples/multi-tenant/pom.xml b/examples/multi-tenant/pom.xml
index d5fb0d5..257be99 100755
--- a/examples/multi-tenant/pom.xml
+++ b/examples/multi-tenant/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-examples-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<name>Keycloak Examples - Multi Tenant</name>
examples/pom.xml 2(+1 -1)
diff --git a/examples/pom.xml b/examples/pom.xml
index 5921ea2..b2f7f2a 100755
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<name>Examples</name>
diff --git a/examples/providers/event-listener-sysout/pom.xml b/examples/providers/event-listener-sysout/pom.xml
index 06504a1..875396b 100755
--- a/examples/providers/event-listener-sysout/pom.xml
+++ b/examples/providers/event-listener-sysout/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-examples-providers-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<name>Event Listener System.out Example</name>
diff --git a/examples/providers/event-store-mem/pom.xml b/examples/providers/event-store-mem/pom.xml
index c1d40ff..eef62a1 100755
--- a/examples/providers/event-store-mem/pom.xml
+++ b/examples/providers/event-store-mem/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-examples-providers-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<name>Event Store In-Mem Example</name>
diff --git a/examples/providers/federation-provider/pom.xml b/examples/providers/federation-provider/pom.xml
index a29520a..1db608c 100755
--- a/examples/providers/federation-provider/pom.xml
+++ b/examples/providers/federation-provider/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-examples-providers-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<name>Properties Authentication Provider Example</name>
examples/providers/pom.xml 2(+1 -1)
diff --git a/examples/providers/pom.xml b/examples/providers/pom.xml
index 21458de..65d719a 100755
--- a/examples/providers/pom.xml
+++ b/examples/providers/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-examples-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<name>Provider Examples</name>
examples/saml/pom.xml 2(+1 -1)
diff --git a/examples/saml/pom.xml b/examples/saml/pom.xml
index c62cd5f..61ac3fb 100755
--- a/examples/saml/pom.xml
+++ b/examples/saml/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-examples-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<name>Provider Examples</name>
examples/saml/post-basic/pom.xml 17(+9 -8)
diff --git a/examples/saml/post-basic/pom.xml b/examples/saml/post-basic/pom.xml
index 062f04d..d4ea4ac 100644
--- a/examples/saml/post-basic/pom.xml
+++ b/examples/saml/post-basic/pom.xml
@@ -22,23 +22,23 @@
</licenses>
<properties>
- <!-- JBoss AS dependency versions -->
- <version.jboss.maven.plugin>7.4.Final</version.jboss.maven.plugin>
-
- <!-- WildFly dependency versions -->
- <version.wildfly.maven.plugin>1.0.1.Final</version.wildfly.maven.plugin>
-
<!-- PicketLink dependency versions -->
<version.picketlink.javaee.bom>2.7.0.Beta2</version.picketlink.javaee.bom>
<!-- Default target container. -->
<target.container>jboss-eap</target.container>
+ <!-- maven-compiler-plugin -->
+ <version.compiler.plugin>3.1</version.compiler.plugin>
+ <!-- maven-deploy-plugin -->
+ <version.deploy.plugin>2.8.1</version.deploy.plugin>
+ <!-- JBoss AS dependency versions -->
+ <version.jboss.maven.plugin>7.4.Final</version.jboss.maven.plugin>
<!-- maven-war-plugin -->
<version.war.plugin>2.1.1</version.war.plugin>
+ <!-- WildFly dependency versions -->
+ <version.wildfly.maven.plugin>1.0.1.Final</version.wildfly.maven.plugin>
- <!-- maven-compiler-plugin -->
- <version.compiler.plugin>3.1</version.compiler.plugin>
<maven.compiler.target>1.6</maven.compiler.target>
<maven.compiler.source>1.6</maven.compiler.source>
</properties>
@@ -50,6 +50,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
+ <version>${version.deploy.plugin}</version>
<configuration>
<skip>true</skip>
</configuration>
diff --git a/examples/saml/post-with-encryption/pom.xml b/examples/saml/post-with-encryption/pom.xml
index 139d4fc..e26e1fb 100755
--- a/examples/saml/post-with-encryption/pom.xml
+++ b/examples/saml/post-with-encryption/pom.xml
@@ -22,23 +22,23 @@
</licenses>
<properties>
- <!-- JBoss AS dependency versions -->
- <version.jboss.maven.plugin>7.4.Final</version.jboss.maven.plugin>
-
- <!-- WildFly dependency versions -->
- <version.wildfly.maven.plugin>1.0.1.Final</version.wildfly.maven.plugin>
-
<!-- PicketLink dependency versions -->
<version.picketlink.javaee.bom>2.7.0.Beta2</version.picketlink.javaee.bom>
<!-- Default target container. -->
<target.container>jboss-eap</target.container>
+ <!-- maven-compiler-plugin -->
+ <version.compiler.plugin>3.1</version.compiler.plugin>
+ <!-- maven-deploy-plugin -->
+ <version.deploy.plugin>2.8.1</version.deploy.plugin>
+ <!-- JBoss AS dependency versions -->
+ <version.jboss.maven.plugin>7.4.Final</version.jboss.maven.plugin>
<!-- maven-war-plugin -->
<version.war.plugin>2.1.1</version.war.plugin>
+ <!-- WildFly dependency versions -->
+ <version.wildfly.maven.plugin>1.0.1.Final</version.wildfly.maven.plugin>
- <!-- maven-compiler-plugin -->
- <version.compiler.plugin>3.1</version.compiler.plugin>
<maven.compiler.target>1.6</maven.compiler.target>
<maven.compiler.source>1.6</maven.compiler.source>
</properties>
@@ -58,6 +58,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
+ <version>${version.deploy.plugin}</version>
<configuration>
<skip>true</skip>
</configuration>
diff --git a/examples/saml/post-with-signature/pom.xml b/examples/saml/post-with-signature/pom.xml
index 6873023..064b642 100755
--- a/examples/saml/post-with-signature/pom.xml
+++ b/examples/saml/post-with-signature/pom.xml
@@ -22,23 +22,23 @@
</licenses>
<properties>
- <!-- JBoss AS dependency versions -->
- <version.jboss.maven.plugin>7.4.Final</version.jboss.maven.plugin>
-
- <!-- WildFly dependency versions -->
- <version.wildfly.maven.plugin>1.0.1.Final</version.wildfly.maven.plugin>
-
<!-- PicketLink dependency versions -->
<version.picketlink.javaee.bom>2.7.0.Beta2</version.picketlink.javaee.bom>
<!-- Default target container. -->
<target.container>jboss-eap</target.container>
+ <!-- maven-compiler-plugin -->
+ <version.compiler.plugin>3.1</version.compiler.plugin>
+ <!-- maven-deploy-plugin -->
+ <version.deploy.plugin>2.8.1</version.deploy.plugin>
+ <!-- JBoss AS dependency versions -->
+ <version.jboss.maven.plugin>7.4.Final</version.jboss.maven.plugin>
<!-- maven-war-plugin -->
<version.war.plugin>2.1.1</version.war.plugin>
+ <!-- WildFly dependency versions -->
+ <version.wildfly.maven.plugin>1.0.1.Final</version.wildfly.maven.plugin>
- <!-- maven-compiler-plugin -->
- <version.compiler.plugin>3.1</version.compiler.plugin>
<maven.compiler.target>1.6</maven.compiler.target>
<maven.compiler.source>1.6</maven.compiler.source>
</properties>
@@ -58,6 +58,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
+ <version>${version.deploy.plugin}</version>
<configuration>
<skip>true</skip>
</configuration>
examples/saml/redirect-basic/pom.xml 16(+9 -7)
diff --git a/examples/saml/redirect-basic/pom.xml b/examples/saml/redirect-basic/pom.xml
index 48ce309..adacc91 100644
--- a/examples/saml/redirect-basic/pom.xml
+++ b/examples/saml/redirect-basic/pom.xml
@@ -22,11 +22,6 @@
</licenses>
<properties>
- <!-- JBoss AS dependency versions -->
- <version.jboss.maven.plugin>7.4.Final</version.jboss.maven.plugin>
-
- <!-- WildFly dependency versions -->
- <version.wildfly.maven.plugin>1.0.1.Final</version.wildfly.maven.plugin>
<!-- PicketLink dependency versions -->
<version.picketlink.javaee.bom>2.7.0.Beta2</version.picketlink.javaee.bom>
@@ -34,11 +29,17 @@
<!-- Default target container. -->
<target.container>jboss-eap</target.container>
+ <!-- maven-compiler-plugin -->
+ <version.compiler.plugin>3.1</version.compiler.plugin>
+ <!-- maven-deploy-plugin -->
+ <version.deploy.plugin>2.8.1</version.deploy.plugin>
+ <!-- JBoss AS dependency versions -->
+ <version.jboss.maven.plugin>7.4.Final</version.jboss.maven.plugin>
<!-- maven-war-plugin -->
<version.war.plugin>2.1.1</version.war.plugin>
+ <!-- WildFly dependency versions -->
+ <version.wildfly.maven.plugin>1.0.1.Final</version.wildfly.maven.plugin>
- <!-- maven-compiler-plugin -->
- <version.compiler.plugin>3.1</version.compiler.plugin>
<maven.compiler.target>1.6</maven.compiler.target>
<maven.compiler.source>1.6</maven.compiler.source>
</properties>
@@ -50,6 +51,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
+ <version>${version.deploy.plugin}</version>
<configuration>
<skip>true</skip>
</configuration>
diff --git a/examples/saml/redirect-with-signature/pom.xml b/examples/saml/redirect-with-signature/pom.xml
index 1d41ffe..a17e41d 100755
--- a/examples/saml/redirect-with-signature/pom.xml
+++ b/examples/saml/redirect-with-signature/pom.xml
@@ -22,23 +22,23 @@
</licenses>
<properties>
- <!-- JBoss AS dependency versions -->
- <version.jboss.maven.plugin>7.4.Final</version.jboss.maven.plugin>
-
- <!-- WildFly dependency versions -->
- <version.wildfly.maven.plugin>1.0.1.Final</version.wildfly.maven.plugin>
-
<!-- PicketLink dependency versions -->
<version.picketlink.javaee.bom>2.7.0.Beta2</version.picketlink.javaee.bom>
<!-- Default target container. -->
<target.container>jboss-eap</target.container>
+ <!-- maven-compiler-plugin -->
+ <version.compiler.plugin>3.1</version.compiler.plugin>
+ <!-- maven-deploy-plugin -->
+ <version.deploy.plugin>2.8.1</version.deploy.plugin>
+ <!-- JBoss AS dependency versions -->
+ <version.jboss.maven.plugin>7.4.Final</version.jboss.maven.plugin>
<!-- maven-war-plugin -->
<version.war.plugin>2.1.1</version.war.plugin>
+ <!-- WildFly dependency versions -->
+ <version.wildfly.maven.plugin>1.0.1.Final</version.wildfly.maven.plugin>
- <!-- maven-compiler-plugin -->
- <version.compiler.plugin>3.1</version.compiler.plugin>
<maven.compiler.target>1.6</maven.compiler.target>
<maven.compiler.source>1.6</maven.compiler.source>
</properties>
@@ -58,6 +58,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
+ <version>${version.deploy.plugin}</version>
<configuration>
<skip>true</skip>
</configuration>
examples/themes/pom.xml 2(+1 -1)
diff --git a/examples/themes/pom.xml b/examples/themes/pom.xml
index ccc7f55..2f4982a 100755
--- a/examples/themes/pom.xml
+++ b/examples/themes/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-examples-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<name>Themes Examples</name>
diff --git a/export-import/export-import-api/pom.xml b/export-import/export-import-api/pom.xml
index 9c8e7e2..f347564 100755
--- a/export-import/export-import-api/pom.xml
+++ b/export-import/export-import-api/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-export-import-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/export-import/export-import-dir/pom.xml b/export-import/export-import-dir/pom.xml
index c709225..d946010 100755
--- a/export-import/export-import-dir/pom.xml
+++ b/export-import/export-import-dir/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-export-import-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/export-import/export-import-single-file/pom.xml b/export-import/export-import-single-file/pom.xml
index fe701aa..2b7e2bd 100755
--- a/export-import/export-import-single-file/pom.xml
+++ b/export-import/export-import-single-file/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-export-import-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/export-import/export-import-zip/pom.xml b/export-import/export-import-zip/pom.xml
index 1d7ba18..fc2bc1a 100755
--- a/export-import/export-import-zip/pom.xml
+++ b/export-import/export-import-zip/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-export-import-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
export-import/pom.xml 2(+1 -1)
diff --git a/export-import/pom.xml b/export-import/pom.xml
index dc3060f..f688691 100755
--- a/export-import/pom.xml
+++ b/export-import/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
federation/kerberos/pom.xml 2(+1 -1)
diff --git a/federation/kerberos/pom.xml b/federation/kerberos/pom.xml
index 2c8ac7e..64e3ca4 100755
--- a/federation/kerberos/pom.xml
+++ b/federation/kerberos/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
federation/ldap/pom.xml 2(+1 -1)
diff --git a/federation/ldap/pom.xml b/federation/ldap/pom.xml
index 0e4afe8..4c2082d 100755
--- a/federation/ldap/pom.xml
+++ b/federation/ldap/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/OrCondition.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/OrCondition.java
index 436355b..d898ffd 100644
--- a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/OrCondition.java
+++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/OrCondition.java
@@ -1,7 +1,5 @@
package org.keycloak.federation.ldap.idm.query.internal;
-import java.util.List;
-
import org.keycloak.federation.ldap.idm.query.Condition;
import org.keycloak.federation.ldap.idm.query.QueryParameter;
diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPIdentityStore.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPIdentityStore.java
index 03b23a3..3dbfd0a 100644
--- a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPIdentityStore.java
+++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPIdentityStore.java
@@ -181,8 +181,8 @@ public class LDAPIdentityStore implements IdentityStore {
public boolean validatePassword(LDAPObject user, String password) {
String userDN = user.getDn().toString();
- if (logger.isDebugEnabled()) {
- logger.debugf("Using DN [%s] for authentication of user", userDN);
+ if (logger.isTraceEnabled()) {
+ logger.tracef("Using DN [%s] for authentication of user", userDN);
}
if (operationManager.authenticate(userDN, password)) {
@@ -259,7 +259,9 @@ public class LDAPIdentityStore implements IdentityStore {
filter.append(getObjectClassesFilter(identityQuery.getObjectClasses()));
filter.append(")");
- logger.infof("Using filter for LDAP search: %s", filter);
+ if (logger.isTraceEnabled()) {
+ logger.tracef("Using filter for LDAP search: %s . Searching in DN: %s", filter, identityQuery.getSearchDn());
+ }
return filter;
}
@@ -378,10 +380,6 @@ public class LDAPIdentityStore implements IdentityStore {
ldapObject.setDn(dn);
ldapObject.setRdnAttributeName(dn.getFirstRdnAttrName());
- if (logger.isTraceEnabled()) {
- logger.tracef("Populating LDAP Object from DN [%s]", entryDN);
- }
-
NamingEnumeration<? extends Attribute> ldapAttributes = attributes.getAll();
// Exact name of attributes might be different
@@ -415,9 +413,6 @@ public class LDAPIdentityStore implements IdentityStore {
if (ldapAttributeName.equalsIgnoreCase(LDAPConstants.OBJECT_CLASS)) {
ldapObject.setObjectClasses(attrValues);
} else {
- if (logger.isTraceEnabled()) {
- logger.tracef("Populating ldap attribute [%s] with value [%s] for DN [%s].", ldapAttributeName, attrValues.toString(), entryDN);
- }
if (attrValues.size() == 1) {
ldapObject.setAttribute(ldapAttributeName, attrValues.iterator().next());
} else {
@@ -431,6 +426,9 @@ public class LDAPIdentityStore implements IdentityStore {
}
}
+ if (logger.isTraceEnabled()) {
+ logger.tracef("Found ldap object [%s] and populated with the attributes [%s]. Read-only attributes are [%s]", ldapObject.getDn().toString(), ldapObject.getAttributes(), ldapObject.getReadOnlyAttributeNames());
+ }
return ldapObject;
} catch (Exception e) {
diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPOperationManager.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPOperationManager.java
index fd88f39..8d934f3 100644
--- a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPOperationManager.java
+++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPOperationManager.java
@@ -128,8 +128,8 @@ public class LDAPOperationManager {
execute(new LdapOperation<SearchResult>() {
@Override
public SearchResult execute(LdapContext context) throws NamingException {
- if (logger.isDebugEnabled()) {
- logger.debugf("Removing entry with DN [%s]", entryDn);
+ if (logger.isTraceEnabled()) {
+ logger.tracef("Removing entry with DN [%s]", entryDn);
}
destroySubcontext(context, entryDn);
return null;
@@ -357,8 +357,8 @@ public class LDAPOperationManager {
public void modifyAttributes(final String dn, final ModificationItem[] mods) {
try {
- if (logger.isDebugEnabled()) {
- logger.debugf("Modifying attributes for entry [%s]: [", dn);
+ if (logger.isTraceEnabled()) {
+ logger.tracef("Modifying attributes for entry [%s]: [", dn);
for (ModificationItem item : mods) {
Object values;
@@ -369,10 +369,10 @@ public class LDAPOperationManager {
values = "No values";
}
- logger.debugf(" Op [%s]: %s = %s", item.getModificationOp(), item.getAttribute().getID(), values);
+ logger.tracef(" Op [%s]: %s = %s", item.getModificationOp(), item.getAttribute().getID(), values);
}
- logger.debugf("]");
+ logger.tracef("]");
}
execute(new LdapOperation<Void>() {
@@ -389,18 +389,18 @@ public class LDAPOperationManager {
public void createSubContext(final String name, final Attributes attributes) {
try {
- if (logger.isDebugEnabled()) {
- logger.debugf("Creating entry [%s] with attributes: [", name);
+ if (logger.isTraceEnabled()) {
+ logger.tracef("Creating entry [%s] with attributes: [", name);
NamingEnumeration<? extends Attribute> all = attributes.getAll();
while (all.hasMore()) {
Attribute attribute = all.next();
- logger.debugf(" %s = %s", attribute.getID(), attribute.get());
+ logger.tracef(" %s = %s", attribute.getID(), attribute.get());
}
- logger.debugf("]");
+ logger.tracef("]");
}
execute(new LdapOperation<Void>() {
diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPConfig.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPConfig.java
index 4ebde77..3317b9d 100644
--- a/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPConfig.java
+++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPConfig.java
@@ -48,7 +48,14 @@ public class LDAPConfig {
}
public String getUsersDn() {
- return config.get(LDAPConstants.USERS_DN);
+ String usersDn = config.get(LDAPConstants.USERS_DN);
+
+ if (usersDn == null) {
+ // Just for the backwards compatibility 1.2 -> 1.3 . Should be removed later.
+ usersDn = config.get("userDnSuffix");
+ }
+
+ return usersDn;
}
public Collection<String> getUserObjectClasses() {
@@ -101,31 +108,13 @@ public class LDAPConfig {
if (uuidAttrName == null) {
// Differences of unique attribute among various vendors
String vendor = getVendor();
- if (vendor != null) {
- switch (vendor) {
- case LDAPConstants.VENDOR_RHDS:
- uuidAttrName = "nsuniqueid";
- break;
- case LDAPConstants.VENDOR_TIVOLI:
- uuidAttrName = "uniqueidentifier";
- break;
- case LDAPConstants.VENDOR_NOVELL_EDIRECTORY:
- uuidAttrName = "guid";
- break;
- case LDAPConstants.VENDOR_ACTIVE_DIRECTORY:
- uuidAttrName = LDAPConstants.OBJECT_GUID;
- }
- }
-
- if (uuidAttrName == null) {
- uuidAttrName = LDAPConstants.ENTRY_UUID;
- }
+ uuidAttrName = LDAPConstants.getUuidAttributeName(vendor);
}
return uuidAttrName;
}
- // TODO: Remove and use mapper instead
+ // TODO: Remove and use mapper instead?
public boolean isUserAccountControlsAfterPasswordUpdate() {
String userAccountCtrls = config.get(LDAPConstants.USER_ACCOUNT_CONTROLS_AFTER_PASSWORD_UPDATE);
return userAccountCtrls==null ? false : Boolean.parseBoolean(userAccountCtrls);
@@ -148,6 +137,12 @@ public class LDAPConfig {
String rdn = config.get(LDAPConstants.RDN_LDAP_ATTRIBUTE);
if (rdn == null) {
rdn = getUsernameLdapAttribute();
+
+ if (rdn.equalsIgnoreCase(LDAPConstants.SAM_ACCOUNT_NAME)) {
+ // Just for the backwards compatibility 1.2 -> 1.3 . Should be removed later.
+ rdn = LDAPConstants.CN;
+ }
+
}
return rdn;
}
diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPFederationProviderFactory.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPFederationProviderFactory.java
index 5c1bf6e..876a96d 100755
--- a/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPFederationProviderFactory.java
+++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPFederationProviderFactory.java
@@ -41,7 +41,7 @@ import java.util.Set;
*/
public class LDAPFederationProviderFactory extends UserFederationEventAwareProviderFactory {
private static final Logger logger = Logger.getLogger(LDAPFederationProviderFactory.class);
- public static final String PROVIDER_NAME = "ldap";
+ public static final String PROVIDER_NAME = LDAPConstants.LDAP_PROVIDER;
private LDAPIdentityStoreRegistry ldapStoreRegistry;
@@ -79,7 +79,7 @@ public class LDAPFederationProviderFactory extends UserFederationEventAwareProvi
// Best effort to create appropriate mappers according to our LDAP config
@Override
- protected void onProviderModelCreated(RealmModel realm, UserFederationProviderModel newProviderModel) {
+ public void onProviderModelCreated(RealmModel realm, UserFederationProviderModel newProviderModel) {
LDAPConfig ldapConfig = new LDAPConfig(newProviderModel.getConfig());
boolean activeDirectory = ldapConfig.isActiveDirectory();
diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPIdentityStoreRegistry.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPIdentityStoreRegistry.java
index c737266..c9d7bb2 100644
--- a/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPIdentityStoreRegistry.java
+++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPIdentityStoreRegistry.java
@@ -55,23 +55,6 @@ public class LDAPIdentityStoreRegistry {
checkSystemProperty("com.sun.jndi.ldap.connect.pool.protocol", "plain");
checkSystemProperty("com.sun.jndi.ldap.connect.pool.debug", "off");
- /*String ldapLoginNameMapping = ldapConfig.get(LDAPConstants.USERNAME_LDAP_ATTRIBUTE);
- if (ldapLoginNameMapping == null) {
- ldapLoginNameMapping = activeDirectory ? LDAPConstants.CN : LDAPConstants.UID;
- }
-
- String ldapFirstNameMapping = activeDirectory ? "givenName" : LDAPConstants.CN;
- String createTimestampMapping = activeDirectory ? "whenCreated" : LDAPConstants.CREATE_TIMESTAMP;
- String modifyTimestampMapping = activeDirectory ? "whenChanged" : LDAPConstants.MODIFY_TIMESTAMP;
- String[] userObjectClasses = getUserObjectClasses(ldapConfig); */
-
-
-/* if (activeDirectory && ldapLoginNameMapping.equals("sAMAccountName")) {
- ldapUserMappingConfig.setBindingDnPropertyName("fullName");
- ldapUserMappingConfig.addAttributeMapping("fullName", LDAPConstants.CN);
- logger.infof("Using 'cn' attribute for DN of user and 'sAMAccountName' for username");
- } */
-
return new LDAPIdentityStore(cfg);
}
diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/RoleLDAPFederationMapper.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/RoleLDAPFederationMapper.java
index 2a78169..165309c 100644
--- a/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/RoleLDAPFederationMapper.java
+++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/RoleLDAPFederationMapper.java
@@ -79,8 +79,7 @@ public class RoleLDAPFederationMapper extends AbstractLDAPFederationMapper {
RoleContainerModel roleContainer = getTargetRoleContainer(mapperModel, realm);
RoleModel role = roleContainer.getRole(roleName);
- // TODO: debug
- logger.infof("Granting role [%s] to user [%s] during import from LDAP", roleName, user.getUsername());
+ logger.debugf("Granting role [%s] to user [%s] during import from LDAP", roleName, user.getUsername());
user.grantRole(role);
}
}
@@ -94,8 +93,7 @@ public class RoleLDAPFederationMapper extends AbstractLDAPFederationMapper {
// Sync roles from LDAP tree and create them in local Keycloak DB (if they don't exist here yet)
protected void syncRolesFromLDAP(UserFederationMapperModel mapperModel, LDAPFederationProvider ldapProvider, RealmModel realm) {
if (!rolesSyncedModels.contains(mapperModel.getId())) {
- // TODO: debug
- logger.infof("Syncing roles from LDAP into Keycloak DB. Mapper is [%s], LDAP provider is [%s]", mapperModel.getName(), ldapProvider.getModel().getDisplayName());
+ logger.debugf("Syncing roles from LDAP into Keycloak DB. Mapper is [%s], LDAP provider is [%s]", mapperModel.getName(), ldapProvider.getModel().getDisplayName());
LDAPIdentityQuery ldapQuery = createRoleQuery(mapperModel, ldapProvider);
@@ -108,7 +106,6 @@ public class RoleLDAPFederationMapper extends AbstractLDAPFederationMapper {
String roleName = ldapRole.getAttributeAsString(rolesRdnAttr);
if (roleContainer.getRole(roleName) == null) {
- // TODO: debug
logger.infof("Syncing role [%s] from LDAP to keycloak DB", roleName);
roleContainer.addRole(roleName);
}
federation/pom.xml 2(+1 -1)
diff --git a/federation/pom.xml b/federation/pom.xml
index b2954f2..6861932 100755
--- a/federation/pom.xml
+++ b/federation/pom.xml
@@ -5,7 +5,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
forms/account-api/pom.xml 2(+1 -1)
diff --git a/forms/account-api/pom.xml b/forms/account-api/pom.xml
index 44319aa..2f8c6f0 100755
--- a/forms/account-api/pom.xml
+++ b/forms/account-api/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-forms-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
forms/account-freemarker/pom.xml 2(+1 -1)
diff --git a/forms/account-freemarker/pom.xml b/forms/account-freemarker/pom.xml
index 9d33498..1b736ae 100755
--- a/forms/account-freemarker/pom.xml
+++ b/forms/account-freemarker/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-forms-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
forms/common-freemarker/pom.xml 2(+1 -1)
diff --git a/forms/common-freemarker/pom.xml b/forms/common-freemarker/pom.xml
index 2457710..9650d36 100755
--- a/forms/common-freemarker/pom.xml
+++ b/forms/common-freemarker/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-forms-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
forms/common-themes/pom.xml 2(+1 -1)
diff --git a/forms/common-themes/pom.xml b/forms/common-themes/pom.xml
index afb9894..3338128 100755
--- a/forms/common-themes/pom.xml
+++ b/forms/common-themes/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-forms-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/index.ftl b/forms/common-themes/src/main/resources/theme/base/admin/index.ftl
index 2cfe128..60edadf 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/index.ftl
+++ b/forms/common-themes/src/main/resources/theme/base/admin/index.ftl
@@ -27,7 +27,7 @@
<script src="${resourceUrl}/lib/fileupload/angular-file-upload.min.js"></script>
<script src="${resourceUrl}/lib/filesaver/FileSaver.js"></script>
- <script src="/auth/js/${resourceVersion}/keycloak.js" type="text/javascript"></script>
+ <script src="${authUrl}/js/${resourceVersion}/keycloak.js" type="text/javascript"></script>
<script src="${resourceUrl}/js/app.js" type="text/javascript"></script>
<script src="${resourceUrl}/js/controllers/realm.js" type="text/javascript"></script>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/brute-force.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/brute-force.html
index ebaa6b4..cd1c754 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/brute-force.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/brute-force.html
@@ -1,5 +1,5 @@
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
- <h1><strong>Settings</strong> {{realm.realm|capitalize}}</h1>
+ <h1>Settings</h1>
<kc-tabs-realm></kc-tabs-realm>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-clustering.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-clustering.html
index c805ccb..71e0850 100644
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-clustering.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-clustering.html
@@ -5,7 +5,7 @@
<li>{{client.clientId}}</li>
</ol>
- <h1><strong>Client</strong> {{client.clientId|capitalize}}</h1>
+ <h1>{{client.clientId|capitalize}}</h1>
<kc-tabs-client></kc-tabs-client>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-credentials.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-credentials.html
index cc6daae..efdc15d 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-credentials.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-credentials.html
@@ -5,7 +5,7 @@
<li>{{client.clientId}}</li>
</ol>
- <h1><strong>Client</strong> {{client.clientId|capitalize}}</h1>
+ <h1>{{client.clientId|capitalize}}</h1>
<kc-tabs-client></kc-tabs-client>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-detail.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-detail.html
index f3b4739..e7e4096 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-detail.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-detail.html
@@ -6,8 +6,8 @@
<li data-ng-hide="create">{{client.clientId}}</li>
</ol>
- <h1 data-ng-show="create"><strong>Add Client</strong></h1>
- <h1 data-ng-hide="create"><strong>Client</strong> {{client.clientId|capitalize}}</h1>
+ <h1 data-ng-show="create">Add Client</h1>
+ <h1 data-ng-hide="create">{{client.clientId|capitalize}}</h1>
<kc-tabs-client></kc-tabs-client>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-import.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-import.html
index bba026b..50cfc0e 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-import.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-import.html
@@ -5,7 +5,7 @@
<li>Import Client</li>
</ol>
- <h1><strong>Import Client</strong></h1>
+ <h1>Import Client</h1>
<form class="form-horizontal" name="realmForm" novalidate>
<fieldset class="border-top">
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-installation.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-installation.html
index e6dd11b..55581c3 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-installation.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-installation.html
@@ -5,7 +5,7 @@
<li>{{client.clientId}}</li>
</ol>
- <h1><strong>Client</strong> {{client.clientId|capitalize}}</h1>
+ <h1>{{client.clientId|capitalize}}</h1>
<kc-tabs-client></kc-tabs-client>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-keys.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-keys.html
index e7fead2..549b056 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-keys.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-keys.html
@@ -5,7 +5,7 @@
<li>{{client.clientId}}</li>
</ol>
- <h1><strong>Client</strong> {{client.clientId|capitalize}}</h1>
+ <h1>{{client.clientId|capitalize}}</h1>
<kc-tabs-client></kc-tabs-client>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-list.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-list.html
index 782c782..36696f7 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-list.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-list.html
@@ -1,6 +1,6 @@
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
<h1>
- <span><strong>Clients</strong> {{realm.realm|capitalize}}</span>
+ <span>Clients</span>
<kc-tooltip>Clients are trusted browser apps and web services in a realm. These clients can request a login. You can also define client specific roles.</kc-tooltip>
</h1>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-mappers.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-mappers.html
index 0f1f274..1e418b4 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-mappers.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-mappers.html
@@ -5,7 +5,7 @@
<li>{{client.clientId}}</li>
</ol>
- <h1><strong>Client</strong> {{client.clientId|capitalize}}</h1>
+ <h1>{{client.clientId|capitalize}}</h1>
<kc-tabs-client></kc-tabs-client>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-mappers-add.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-mappers-add.html
index a7a3b11..c3fda83 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-mappers-add.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-mappers-add.html
@@ -7,7 +7,7 @@
<li class="active">Add Builtin Protocol Mappers</li>
</ol>
- <h1><strong>Add Builtin Protocol Mapper</strong></h1>
+ <h1>Add Builtin Protocol Mapper</h1>
<table class="table table-striped table-bordered">
<thead>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-revocation.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-revocation.html
index 38ce042..522f554 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-revocation.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-revocation.html
@@ -5,7 +5,7 @@
<li>{{client.clientId}}</li>
</ol>
- <h1><strong>Client</strong> {{client.clientId|capitalize}}</h1>
+ <h1>{{client.clientId|capitalize}}</h1>
<kc-tabs-client></kc-tabs-client>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-role-detail.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-role-detail.html
index 706c2d3..2c267ca 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-role-detail.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-role-detail.html
@@ -8,8 +8,8 @@
<li data-ng-hide="create">{{role.name}}</li>
</ol>
- <h1 data-ng-show="create"><strong>Add Role</strong></h1>
- <h1 data-ng-hide="create"><strong>Role</strong> {{role.name}}</h1>
+ <h1 data-ng-show="create">Add Role</h1>
+ <h1 data-ng-hide="create">{{role.name|capitalize}}</h1>
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageClients">
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-role-list.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-role-list.html
index e892d35..c9ec943 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-role-list.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-role-list.html
@@ -5,7 +5,7 @@
<li>{{client.clientId}}</li>
</ol>
- <h1><strong>Client</strong> {{client.clientId|capitalize}}</h1>
+ <h1>{{client.clientId|capitalize}}</h1>
<kc-tabs-client></kc-tabs-client>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-saml-key-export.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-saml-key-export.html
index 7d0facb..70a4c7d 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-saml-key-export.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-saml-key-export.html
@@ -7,7 +7,7 @@
<li class="active">SAML {{keyType}} Key Export</li>
</ol>
- <h1><strong>Export SAML Key</strong> {{client.clientId|capitalize}}</h1>
+ <h1>Export SAML Key {{client.clientId|capitalize}}</h1>
<form class="form-horizontal" name="keyForm" novalidate kc-read-only="!access.manageRealm">
<fieldset class="form-group col-sm-10">
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-saml-key-import.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-saml-key-import.html
index 76ee50d..8ea421b 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-saml-key-import.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-saml-key-import.html
@@ -7,7 +7,7 @@
<li class="active">SAML {{keyType}} Key Import</li>
</ol>
- <h1><strong>Import SAML Key</strong> {{client.clientId|capitalize}}</h1>
+ <h1>Import SAML Key {{client.clientId|capitalize}}</h1>
<form class="form-horizontal" name="keyForm" novalidate kc-read-only="!access.manageRealm">
<fieldset>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-saml-keys.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-saml-keys.html
index 5f0f1ef..74eb840 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-saml-keys.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-saml-keys.html
@@ -5,7 +5,7 @@
<li>{{client.clientId}}</li>
</ol>
- <h1><strong>Client</strong> {{client.clientId|capitalize}}</h1>
+ <h1>{{client.clientId|capitalize}}</h1>
<kc-tabs-client></kc-tabs-client>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-scope-mappings.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-scope-mappings.html
index 5340685..79eccd5 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-scope-mappings.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-scope-mappings.html
@@ -5,7 +5,7 @@
<li>{{client.clientId}}</li>
</ol>
- <h1><strong>Client</strong> {{client.clientId|capitalize}}</h1>
+ <h1>{{client.clientId|capitalize}}</h1>
<kc-tabs-client></kc-tabs-client>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-sessions.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-sessions.html
index f936703..838b166 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-sessions.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-sessions.html
@@ -5,7 +5,7 @@
<li>{{client.clientId}}</li>
</ol>
- <h1><strong>Client</strong> {{client.clientId|capitalize}}</h1>
+ <h1>{{client.clientId|capitalize}}</h1>
<kc-tabs-client></kc-tabs-client>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/defense-headers.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/defense-headers.html
index f7cda27..ca8511c 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/defense-headers.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/defense-headers.html
@@ -1,5 +1,5 @@
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
- <h1><strong>Settings</strong> {{realm.realm|capitalize}}</h1>
+ <h1>Settings</h1>
<kc-tabs-realm></kc-tabs-realm>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/federated-generic.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/federated-generic.html
index f0d8774..bff634a 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/federated-generic.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/federated-generic.html
@@ -5,8 +5,8 @@
<li data-ng-show="create">Add User Federation Provider</li>
</ol>
- <h1 data-ng-hide="create"><strong>{{instance.providerName|capitalize}} User Federation Provider</strong> {{instance.displayName|capitalize}}</h1>
- <h1 data-ng-show="create"><strong>Add {{instance.providerName|capitalize}} User Federation Provider</strong></h1>
+ <h1 data-ng-hide="create">{{instance.providerName|capitalize}}</h1>
+ <h1 data-ng-show="create">Add {{instance.providerName|capitalize}} User Federation Provide</h1>
<ul class="nav nav-tabs" data-ng-hide="create">
<li class="active"><a href="#/realms/{{realm.realm}}/user-federation/providers/{{instance.providerName}}/{{instance.id}}">Settings</a></li>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/federated-kerberos.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/federated-kerberos.html
index b2f4701..34510ff 100644
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/federated-kerberos.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/federated-kerberos.html
@@ -5,8 +5,8 @@
<li data-ng-show="create">Add User Federation Provider</li>
</ol>
- <h1 data-ng-hide="create"><strong>Kerberos User Federation Provider</strong> {{instance.displayName|capitalize}}</h1>
- <h1 data-ng-show="create"><strong>Add Kerberos User Federation Provider</strong></h1>
+ <h1 data-ng-hide="create">Kerberos</h1>
+ <h1 data-ng-show="create">Add Kerberos User Federation Provider</h1>
<ul class="nav nav-tabs" data-ng-hide="create">
<li class="active"><a href="#/realms/{{realm.realm}}/user-federation/providers/{{instance.providerName}}/{{instance.id}}">Settings</a></li>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/federated-ldap.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/federated-ldap.html
index a3710c8..5c8bf46 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/federated-ldap.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/federated-ldap.html
@@ -5,8 +5,8 @@
<li data-ng-show="create">Add User Federation Provider</li>
</ol>
- <h1 data-ng-hide="create"><strong>LDAP User Federation Provider</strong> {{instance.displayName|capitalize}}</h1>
- <h1 data-ng-show="create"><strong>Add LDAP User Federation Provider</strong></h1>
+ <h1 data-ng-hide="create">LDAP</h1>
+ <h1 data-ng-show="create">Add LDAP User Federation Provider</h1>
<ul class="nav nav-tabs" data-ng-hide="create">
<li class="active"><a href="#/realms/{{realm.realm}}/user-federation/providers/{{instance.providerName}}/{{instance.id}}">Settings</a></li>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/federated-mapper-detail.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/federated-mapper-detail.html
index f06d032..d57d6ea 100644
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/federated-mapper-detail.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/federated-mapper-detail.html
@@ -7,8 +7,8 @@
<li class="active" data-ng-hide="create">{{mapper.name}}</li>
</ol>
- <h1 data-ng-hide="create"><strong>User Federation Mapper</strong> {{mapper.name}}</h1>
- <h1 data-ng-show="create"><strong>Add User Federation Mapper</strong></h1>
+ <h1 data-ng-hide="create">{{mapper.name|capitalize}}</h1>
+ <h1 data-ng-show="create">Add User Federation Mapper</h1>
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm">
<fieldset>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/federated-mappers.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/federated-mappers.html
index d650100..2401b47 100644
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/federated-mappers.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/federated-mappers.html
@@ -5,7 +5,7 @@
<li>User Federation Mappers</li>
</ol>
- <h1><strong>{{provider.providerName === 'ldap' ? 'LDAP' : (provider.providerName|capitalize)}} User Federation Provider</strong> {{provider.displayName|capitalize}}</h1>
+ <h1>{{provider.providerName === 'ldap' ? 'LDAP' : (provider.providerName|capitalize)}}</h1>
<ul class="nav nav-tabs" data-ng-hide="create">
<li><a href="#/realms/{{realm.realm}}/user-federation/providers/{{provider.providerName}}/{{provider.id}}">Settings</a></li>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/identity-provider-mapper-detail.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/identity-provider-mapper-detail.html
index e9eef49..14bdd02 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/identity-provider-mapper-detail.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/identity-provider-mapper-detail.html
@@ -4,11 +4,11 @@
<li><a href="#/realms/{{realm.realm}}/identity-provider-settings/provider/{{identityProvider.providerId}}/{{identityProvider.alias}}">{{identityProvider.alias}}</a></li>
<li><a href="#/realms/{{realm.realm}}/identity-provider-mappers/{{identityProvider.alias}}/mappers">Identity Provider Mappers</a></li>
<li class="active" data-ng-show="create">Create IdentityProvider Mapper</li>
- <li class="active" data-ng-hide="create">{{mapper.name}}</li>
+ <li class="active" data-ng-hide="create">{{mapper.name|capitalize}}</li>
</ol>
- <h1 data-ng-hide="create"><strong>Identity Provider Mapper</strong> {{mapper.name}}</h1>
- <h1 data-ng-show="create"><strong>Add Identity Provider Mapper</strong></h1>
+ <h1 data-ng-hide="create">{{mapper.name|capitalize}}</h1>
+ <h1 data-ng-show="create">Add Identity Provider Mapper</h1>
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm">
<fieldset>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/identity-provider-mappers.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/identity-provider-mappers.html
index e1012ef..20339e1 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/identity-provider-mappers.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/identity-provider-mappers.html
@@ -4,7 +4,7 @@
<li>{{identityProvider.alias}}</li>
</ol>
- <h1><strong>Identity Provider</strong> {{identityProvider.alias|capitalize}}</h1>
+ <h1>{{identityProvider.alias|capitalize}}</h1>
<ul class="nav nav-tabs" data-ng-hide="newIdentityProvider">
<li><a href="#/realms/{{realm.realm}}/identity-provider-settings/provider/{{identityProvider.providerId}}/{{identityProvider.alias}}">Settings</a></li>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/protocol-mapper-detail.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/protocol-mapper-detail.html
index 4c519dc..3877ff7 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/protocol-mapper-detail.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/protocol-mapper-detail.html
@@ -8,8 +8,8 @@
<li class="active" data-ng-hide="create">{{mapper.name}}</li>
</ol>
- <h1 data-ng-show="create"><strong>Create Protocol Mapper</strong></h1>
- <h1 data-ng-hide="create"><strong>Protocol Mapper</strong> {{mapper.name}}</h1>
+ <h1 data-ng-show="create">Create Protocol Mapper</h1>
+ <h1 data-ng-hide="create">{{mapper.name|capitalize}}</h1>
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm">
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-cache-settings.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-cache-settings.html
index 78e190b..aa829d7 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-cache-settings.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-cache-settings.html
@@ -1,5 +1,5 @@
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
- <h1><strong>Settings</strong> {{realm.realm|capitalize}}</h1>
+ <h1>Settings</h1>
<kc-tabs-realm></kc-tabs-realm>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-credentials.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-credentials.html
index 9c6c39a..aca4d4d 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-credentials.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-credentials.html
@@ -1,5 +1,5 @@
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
- <h1><strong>Settings</strong> {{realm.realm|capitalize}}</h1>
+ <h1>Settings</h1>
<kc-tabs-realm></kc-tabs-realm>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-default-roles.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-default-roles.html
index 732aeea..33fec9e 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-default-roles.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-default-roles.html
@@ -1,5 +1,5 @@
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
- <h1><strong>Roles</strong> {{realm.realm|capitalize}}</h1>
+ <h1>Roles</h1>
<ul class="nav nav-tabs">
<li><a href="#/realms/{{realm.realm}}/roles">Realm Roles</a></li>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-detail.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-detail.html
index d966acd..67d7534 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-detail.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-detail.html
@@ -1,5 +1,5 @@
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
- <h1 data-ng-hide="createRealm"><strong>Settings</strong> {{realm.realm|capitalize}}</h1>
+ <h1 data-ng-hide="createRealm">Settings</h1>
<h1 data-ng-show="createRealm">Add Realm</h1>
<kc-tabs-realm></kc-tabs-realm>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events.html
index 2540603..406f312 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events.html
@@ -1,6 +1,6 @@
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
<h1>
- <span><strong>Events</strong> {{realm.realm|capitalize}}</span>
+ <span>Events</span>
<kc-tooltip>Displays saved events for the realm. Events are related to user accounts, for example a user login. To enable persisted events go to config.</kc-tooltip>
</h1>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events-admin.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events-admin.html
index cb32dc4..57996c8 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events-admin.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events-admin.html
@@ -1,6 +1,6 @@
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
<h1>
- <span><strong>Admin Events</strong> {{realm.realm|capitalize}}</span>
+ <span>Admin Events</span>
<kc-tooltip>Displays saved admin events for the realm. Events are related to admin account, for example a realm creation. To enable persisted events go to config.</kc-tooltip>
</h1>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events-config.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events-config.html
index 11c2f00..06cd18a 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events-config.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events-config.html
@@ -1,6 +1,6 @@
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
<h1>
- <span><strong>Events Config</strong> {{realm.realm|capitalize}}</span>
+ <span>Events Config</span>
<kc-tooltip>Displays configuration options to enable persistence of user and admin events.</kc-tooltip>
</h1>
@@ -10,7 +10,7 @@
<li data-ng-class="(path[2] == 'events-settings') && 'active'"><a href="#/realms/{{realm.realm}}/events-settings">Config</a></li>
</ul>
<div id="content">
- <h2><span>{{realm.realm}}</span> Events Config</h2>
+ <h2>Events Config</h2>
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageEvents">
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider.html
index 9a2a28f..3d82adc 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider.html
@@ -1,5 +1,5 @@
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
- <h1><strong>Identity Providers</strong> {{realm.realm|capitalize}}</h1>
+ <h1>Identity Providers</h1>
<form name="realmForm" novalidate class="form-horizontal">
<fieldset>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-export.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-export.html
index 3ddb612..37302a2 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-export.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-export.html
@@ -4,8 +4,8 @@
<li>{{identityProvider.alias}}</li>
</ol>
- <h1 data-ng-hide="create"><strong>Identity Provider</strong> {{identityProvider.alias|capitalize}}</h1>
- <h1 data-ng-show="create"><strong>Add OpenID Connect Identity Provider</strong></h1>
+ <h1 data-ng-hide="create">{{identityProvider.alias|capitalize}}</h1>
+ <h1 data-ng-show="create">Add OpenID Connect Identity Provider</h1>
<ul class="nav nav-tabs" data-ng-hide="newIdentityProvider">
<li><a href="#/realms/{{realm.realm}}/identity-provider-settings/provider/{{identityProvider.providerId}}/{{identityProvider.alias}}">Settings</a></li>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-oidc.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-oidc.html
index d2a267b..9d3eec2 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-oidc.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-oidc.html
@@ -4,8 +4,8 @@
<li>{{identityProvider.alias}}</li>
</ol>
- <h1 data-ng-hide="create"><strong>Identity Provider</strong> {{identityProvider.alias|capitalize}}</h1>
- <h1 data-ng-show="create"><strong>Add OpenID Connect Identity Provider</strong></h1>
+ <h1 data-ng-hide="create">{{identityProvider.alias|capitalize}}</h1>
+ <h1 data-ng-show="create">Add OpenID Connect Identity Provider</h1>
<ul class="nav nav-tabs" data-ng-hide="newIdentityProvider">
<li class="active"><a href="#/realms/{{realm.realm}}/identity-provider-settings/provider/{{identityProvider.providerId}}/{{identityProvider.alias}}">Settings</a></li>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-saml.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-saml.html
index d2aaf4e..21000f7 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-saml.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-saml.html
@@ -4,8 +4,8 @@
<li>{{identityProvider.alias}}</li>
</ol>
- <h1 data-ng-hide="create"><strong>Identity Provider</strong> {{identityProvider.alias|capitalize}}</h1>
- <h1 data-ng-show="create"><strong>Add SAML Identity Provider</strong></h1>
+ <h1 data-ng-hide="create">{{identityProvider.alias|capitalize}}</h1>
+ <h1 data-ng-show="create">Add SAML Identity Provider</h1>
<ul class="nav nav-tabs" data-ng-hide="newIdentityProvider">
<li class="active"><a href="#/realms/{{realm.realm}}/identity-provider-settings/provider/{{identityProvider.providerId}}/{{identityProvider.alias}}">Settings</a></li>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-social.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-social.html
index 623bcf0..bf48cf7 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-social.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-social.html
@@ -4,8 +4,8 @@
<li>{{identityProvider.alias}}</li>
</ol>
- <h1 data-ng-hide="create"><strong>Identity Provider</strong> {{identityProvider.alias|capitalize}}</h1>
- <h1 data-ng-show="create"><strong>Add Social Identity Provider</strong></h1>
+ <h1 data-ng-hide="create">{{identityProvider.alias|capitalize}}</h1>
+ <h1 data-ng-show="create">Add Social Identity Provider</h1>
<ul class="nav nav-tabs" data-ng-hide="newIdentityProvider">
<li class="active"><a href="#/realms/{{realm.realm}}/identity-provider-settings/provider/{{identityProvider.providerId}}/{{identityProvider.alias}}">Settings</a></li>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-stackoverflow-ext.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-stackoverflow-ext.html
index fe676a4..af49b3b 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-stackoverflow-ext.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-stackoverflow-ext.html
@@ -1,7 +1,7 @@
- <div class="form-group clearfix">
- <label class="col-md-2 control-label" for="clientId">Key <span class="required">*</span></label>
- <div class="col-md-6">
- <input class="form-control" id="clientId" type="text" ng-model="identityProvider.config.key" required>
- </div>
- <kc-tooltip>The Key obtained from Stack Overflow client registration.</kc-tooltip>
- </div>
+<div class="form-group clearfix">
+ <label class="col-md-2 control-label" for="clientId">Key <span class="required">*</span></label>
+ <div class="col-md-6">
+ <input class="form-control" id="clientId" type="text" ng-model="identityProvider.config.key" required>
+ </div>
+ <kc-tooltip>The Key obtained from Stack Overflow client registration.</kc-tooltip>
+</div>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-keys.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-keys.html
index ddaf069..c89adf9 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-keys.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-keys.html
@@ -1,5 +1,5 @@
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
- <h1><strong>Settings</strong> {{realm.realm|capitalize}}</h1>
+ <h1>Settings</h1>
<kc-tabs-realm></kc-tabs-realm>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-login-settings.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-login-settings.html
index 34679ae..024e0c1 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-login-settings.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-login-settings.html
@@ -1,5 +1,5 @@
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
- <h1><strong>Settings</strong> {{realm.realm|capitalize}}</h1>
+ <h1>Settings</h1>
<kc-tabs-realm></kc-tabs-realm>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-smtp.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-smtp.html
index eb2759b..30ad48d 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-smtp.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-smtp.html
@@ -1,5 +1,5 @@
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
- <h1><strong>Settings</strong> {{realm.realm|capitalize}}</h1>
+ <h1>Settings</h1>
<kc-tabs-realm></kc-tabs-realm>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-theme-settings.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-theme-settings.html
index f4b7234..5c51bba 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-theme-settings.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-theme-settings.html
@@ -1,5 +1,5 @@
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
- <h1><strong>Settings</strong> {{realm.realm|capitalize}}</h1>
+ <h1>Settings</h1>
<kc-tabs-realm></kc-tabs-realm>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-tokens.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-tokens.html
index 6fd68b7..c23fa66 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-tokens.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-tokens.html
@@ -1,5 +1,5 @@
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
- <h1><strong>Settings</strong> {{realm.realm|capitalize}}</h1>
+ <h1>Settings</h1>
<kc-tabs-realm></kc-tabs-realm>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/role-detail.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/role-detail.html
index aa21bd8..6c80c97 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/role-detail.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/role-detail.html
@@ -6,8 +6,8 @@
<li data-ng-show="create">Add Role</li>
</ol>
- <h1 data-ng-hide="create"><strong>Role</strong> {{role.name}}</h1>
- <h1 data-ng-show="create"><strong>Add Role</strong></h1>
+ <h1 data-ng-hide="create">{{role.name|capitalize}}</h1>
+ <h1 data-ng-show="create">Add Role</h1>
<form class="form-horizontal clearfix" name="realmForm" novalidate kc-read-only="!access.manageRealm">
<fieldset>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/role-list.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/role-list.html
index 010b29e..0c44d31 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/role-list.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/role-list.html
@@ -1,5 +1,5 @@
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
- <h1><strong>Roles</strong> {{realm.realm|capitalize}}</h1>
+ <h1>Roles</h1>
<ul class="nav nav-tabs">
<li class="active"><a href="#/realms/{{realm.realm}}/roles">Realm Roles</a></li>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/role-mappings.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/role-mappings.html
index 0bdc22e..94bf899 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/role-mappings.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/role-mappings.html
@@ -4,7 +4,7 @@
<li>{{user.username}}</li>
</ol>
- <h1><strong>User</strong> {{user.username|capitalize}}</h1>
+ <h1>{{user.username|capitalize}}</h1>
<kc-tabs-user></kc-tabs-user>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/session-realm.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/session-realm.html
index 58085d5..8b62f1a 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/session-realm.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/session-realm.html
@@ -1,5 +1,5 @@
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
- <h1><strong>Sessions</strong> {{realm.realm|capitalize}}</h1>
+ <h1>Sessions</h1>
<ul class="nav nav-tabs">
<li class="active"><a href="#/realms/{{realm.realm}}/sessions/realm">Realm Sessions</a></li>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/session-revocation.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/session-revocation.html
index 9743018..d16b22f 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/session-revocation.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/session-revocation.html
@@ -1,5 +1,5 @@
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
- <h1><strong>Sessions</strong> {{realm.realm|capitalize}}</h1>
+ <h1>Sessions</h1>
<ul class="nav nav-tabs">
<li><a href="#/realms/{{realm.realm}}/sessions/realm">Realm Sessions</a></li>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-consents.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-consents.html
index 5b9a7a8..a22d0aa 100644
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-consents.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-consents.html
@@ -4,7 +4,7 @@
<li>{{user.username}}</li>
</ol>
- <h1><strong>User</strong> {{user.username|capitalize}}</h1>
+ <h1>{{user.username|capitalize}}</h1>
<kc-tabs-user></kc-tabs-user>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-credentials.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-credentials.html
index a564144..7c12f48 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-credentials.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-credentials.html
@@ -4,7 +4,7 @@
<li>{{user.username}}</li>
</ol>
- <h1><strong>User</strong> {{user.username|capitalize}}</h1>
+ <h1>{{user.username|capitalize}}</h1>
<kc-tabs-user></kc-tabs-user>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-detail.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-detail.html
index 1dcadd4..09a3fc4 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-detail.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-detail.html
@@ -5,7 +5,7 @@
<li data-ng-show="create">Add User</li>
</ol>
- <h1 data-ng-hide="create"><strong>User</strong> {{user.username|capitalize}}</h1>
+ <h1 data-ng-hide="create">{{user.username|capitalize}}</h1>
<h1 data-ng-show="create">Add User</h1>
<kc-tabs-user></kc-tabs-user>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-federated-identity.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-federated-identity.html
index 0a22aeb..14d8d67 100644
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-federated-identity.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-federated-identity.html
@@ -4,7 +4,7 @@
<li>{{user.username}}</li>
</ol>
- <h1><strong>User</strong> {{user.username|capitalize}}</h1>
+ <h1>{{user.username|capitalize}}</h1>
<kc-tabs-user></kc-tabs-user>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-federation.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-federation.html
index 63c89c0..2162127 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-federation.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-federation.html
@@ -1,6 +1,6 @@
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
<h1>
- <span><strong>User Federation</strong> {{realm.realm|capitalize}}</span>
+ <span>User Federation</span>
</h1>
<table class="table table-striped table-bordered">
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-list.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-list.html
index 4498988..9a042e3 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-list.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-list.html
@@ -1,5 +1,5 @@
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
- <h1><strong>Users</strong> {{realm.realm|capitalize}}</h1>
+ <h1>Users</h1>
<table class="table table-striped table-bordered">
<caption data-ng-show="users" class="hidden">Table of realm users</caption>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-sessions.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-sessions.html
index ee47235..762dda9 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-sessions.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-sessions.html
@@ -4,7 +4,7 @@
<li>{{user.username}}</li>
</ol>
- <h1><strong>User</strong> {{user.username|capitalize}}</h1>
+ <h1>{{user.username|capitalize}}</h1>
<kc-tabs-user></kc-tabs-user>
diff --git a/forms/common-themes/src/main/resources/theme/keycloak/login/resources/css/login.css b/forms/common-themes/src/main/resources/theme/keycloak/login/resources/css/login.css
index 18d97e0..b64bdc7 100644
--- a/forms/common-themes/src/main/resources/theme/keycloak/login/resources/css/login.css
+++ b/forms/common-themes/src/main/resources/theme/keycloak/login/resources/css/login.css
@@ -121,11 +121,6 @@
display: block;
}
-#kc-login {
- float: right;
- margin-left: 10px;
-}
-
#kc-feedback-wrapper {
display: inline-block;
width: auto;
forms/email-api/pom.xml 2(+1 -1)
diff --git a/forms/email-api/pom.xml b/forms/email-api/pom.xml
index 17f17b6..4eb50b9 100755
--- a/forms/email-api/pom.xml
+++ b/forms/email-api/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-forms-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
forms/email-freemarker/pom.xml 2(+1 -1)
diff --git a/forms/email-freemarker/pom.xml b/forms/email-freemarker/pom.xml
index d38e348..31a5f4a 100755
--- a/forms/email-freemarker/pom.xml
+++ b/forms/email-freemarker/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-forms-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
forms/login-api/pom.xml 2(+1 -1)
diff --git a/forms/login-api/pom.xml b/forms/login-api/pom.xml
index 90ddbdc..da72ddf 100755
--- a/forms/login-api/pom.xml
+++ b/forms/login-api/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-forms-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
forms/login-freemarker/pom.xml 2(+1 -1)
diff --git a/forms/login-freemarker/pom.xml b/forms/login-freemarker/pom.xml
index d580f17..7e18b3a 100755
--- a/forms/login-freemarker/pom.xml
+++ b/forms/login-freemarker/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-forms-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
forms/pom.xml 2(+1 -1)
diff --git a/forms/pom.xml b/forms/pom.xml
index f070014..5fa20aa 100755
--- a/forms/pom.xml
+++ b/forms/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
integration/adapter-core/pom.xml 2(+1 -1)
diff --git a/integration/adapter-core/pom.xml b/integration/adapter-core/pom.xml
index b519e47..d9a39ff 100755
--- a/integration/adapter-core/pom.xml
+++ b/integration/adapter-core/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
integration/admin-client/pom.xml 10(+4 -6)
diff --git a/integration/admin-client/pom.xml b/integration/admin-client/pom.xml
index 75cf5bf..6a4b41c 100755
--- a/integration/admin-client/pom.xml
+++ b/integration/admin-client/pom.xml
@@ -5,7 +5,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -32,21 +32,19 @@
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>jaxrs-api</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.jboss.resteasy</groupId>
- <artifactId>resteasy-jaxrs</artifactId>
+ <version>${resteasy.latest.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
+ <version>${resteasy.latest.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson-provider</artifactId>
+ <version>${resteasy.latest.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/UsersResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/UsersResource.java
index dc53fdf..9b70421 100755
--- a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/UsersResource.java
+++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/UsersResource.java
@@ -17,7 +17,7 @@ public interface UsersResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
- public List<UserRepresentation> search(@QueryParam("username") String username,
+ List<UserRepresentation> search(@QueryParam("username") String username,
@QueryParam("firstName") String firstName,
@QueryParam("lastName") String lastName,
@QueryParam("email") String email,
@@ -26,7 +26,7 @@ public interface UsersResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
- public List<UserRepresentation> search(@QueryParam("search") String search,
+ List<UserRepresentation> search(@QueryParam("search") String search,
@QueryParam("first") Integer firstResult,
@QueryParam("max") Integer maxResults);
@@ -34,7 +34,7 @@ public interface UsersResource {
@Consumes(MediaType.APPLICATION_JSON)
Response create(UserRepresentation userRepresentation);
- @Path("{username}")
- public UserResource get(@PathParam("username") String username);
+ @Path("{id}")
+ UserResource get(@PathParam("id") String id);
}
diff --git a/integration/as7-eap6/as7-adapter/pom.xml b/integration/as7-eap6/as7-adapter/pom.xml
index fcba0a0..93ddc0f 100755
--- a/integration/as7-eap6/as7-adapter/pom.xml
+++ b/integration/as7-eap6/as7-adapter/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
integration/as7-eap6/as7-server-subsystem/pom.xml 104(+104 -0)
diff --git a/integration/as7-eap6/as7-server-subsystem/pom.xml b/integration/as7-eap6/as7-server-subsystem/pom.xml
new file mode 100755
index 0000000..572c959
--- /dev/null
+++ b/integration/as7-eap6/as7-server-subsystem/pom.xml
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+~ Copyright 2013 JBoss Inc
+~
+~ Licensed under the Apache License, Version 2.0 (the "License");
+~ you may not use this file except in compliance with the License.
+~ You may obtain a copy of the License at
+~
+~ http://www.apache.org/licenses/LICENSE-2.0
+~
+~ Unless required by applicable law or agreed to in writing, software
+~ distributed under the License is distributed on an "AS IS" BASIS,
+~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+~ See the License for the specific language governing permissions and
+~ limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.keycloak</groupId>
+ <artifactId>keycloak-parent</artifactId>
+ <version>1.4.0.Final-SNAPSHOT</version>
+ <relativePath>../../../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>keycloak-as7-server-subsystem</artifactId>
+ <name>Keycloak AS7 / EAP 6 Server Subsystem</name>
+ <description/>
+ <packaging>jar</packaging>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <redirectTestOutputToFile>false</redirectTestOutputToFile>
+ <enableAssertions>true</enableAssertions>
+ <systemProperties>
+ <property>
+ <name>jboss.home</name>
+ <value>${jboss.home}</value>
+ </property>
+ </systemProperties>
+ <includes>
+ <include>**/*TestCase.java</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.jboss.as</groupId>
+ <artifactId>jboss-as-naming</artifactId>
+ <version>${jboss.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.as</groupId>
+ <artifactId>jboss-as-server</artifactId>
+ <version>${jboss.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.as</groupId>
+ <artifactId>jboss-as-ee</artifactId>
+ <version>${jboss.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.as</groupId>
+ <artifactId>jboss-as-web</artifactId>
+ <version>${jboss.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.logging</groupId>
+ <artifactId>jboss-logging-annotations</artifactId>
+ <version>${jboss-logging-tools.version}</version>
+ <!-- This is a compile-time dependency of this project, but is not needed at compile or runtime by other
+ projects that depend on this project.-->
+ <scope>provided</scope>
+ <optional>true</optional>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.logging</groupId>
+ <artifactId>jboss-logging-processor</artifactId>
+ <!-- This is a compile-time dependency of this project, but is not needed at compile or runtime by other
+ projects that depend on this project.-->
+ <scope>provided</scope>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.msc</groupId>
+ <artifactId>jboss-msc</artifactId>
+ <version>1.0.2.GA</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/integration/as7-eap6/as7-server-subsystem/src/main/java/org/keycloak/subsystem/server/as7/KeycloakAdapterConfigService.java b/integration/as7-eap6/as7-server-subsystem/src/main/java/org/keycloak/subsystem/server/as7/KeycloakAdapterConfigService.java
new file mode 100755
index 0000000..9e13799
--- /dev/null
+++ b/integration/as7-eap6/as7-server-subsystem/src/main/java/org/keycloak/subsystem/server/as7/KeycloakAdapterConfigService.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.keycloak.subsystem.server.as7;
+
+/**
+ * This service keeps track of the entire Keycloak management model so as to provide
+ * adapter configuration to each deployment at deploy time.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
+ */
+public final class KeycloakAdapterConfigService {
+
+ static final KeycloakAdapterConfigService INSTANCE = new KeycloakAdapterConfigService();
+
+ static final String DEPLOYMENT_NAME = "keycloak-server";
+
+ private String webContext;
+
+
+ private KeycloakAdapterConfigService() {
+ }
+
+ void setWebContext(String webContext) {
+ this.webContext = webContext;
+ }
+
+ String getWebContext() {
+ return webContext;
+ }
+
+ boolean isKeycloakServerDeployment(String deploymentName) {
+ return DEPLOYMENT_NAME.equals(deploymentName);
+ }
+}
diff --git a/integration/as7-eap6/as7-server-subsystem/src/main/java/org/keycloak/subsystem/server/as7/KeycloakExtension.java b/integration/as7-eap6/as7-server-subsystem/src/main/java/org/keycloak/subsystem/server/as7/KeycloakExtension.java
new file mode 100755
index 0000000..296faa5
--- /dev/null
+++ b/integration/as7-eap6/as7-server-subsystem/src/main/java/org/keycloak/subsystem/server/as7/KeycloakExtension.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.keycloak.subsystem.server.as7;
+
+import org.jboss.as.controller.Extension;
+import org.jboss.as.controller.ExtensionContext;
+import org.jboss.as.controller.PathElement;
+import org.jboss.as.controller.ResourceDefinition;
+import org.jboss.as.controller.SubsystemRegistration;
+import org.jboss.as.controller.descriptions.StandardResourceDescriptionResolver;
+import org.jboss.as.controller.parsing.ExtensionParsingContext;
+
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SUBSYSTEM;
+import static org.keycloak.subsystem.server.logging.KeycloakLogger.ROOT_LOGGER;
+
+
+/**
+ * Main Extension class for the subsystem.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
+ */
+public class KeycloakExtension implements Extension {
+
+ static final String SUBSYSTEM_NAME = "keycloak-server";
+ static final String NAMESPACE = "urn:jboss:domain:keycloak-server:1.1";
+ static final PathElement PATH_SUBSYSTEM = PathElement.pathElement(SUBSYSTEM, SUBSYSTEM_NAME);
+
+ private static final String RESOURCE_NAME = KeycloakExtension.class.getPackage().getName() + ".LocalDescriptions";
+ private static final ResourceDefinition KEYCLOAK_SUBSYSTEM_RESOURCE = new KeycloakSubsystemDefinition();
+ private static final KeycloakSubsystemParser PARSER = new KeycloakSubsystemParser();
+ private static final int MGMT_API_VERSION_MAJOR = 1;
+ private static final int MGMT_API_VERSION_MINOR = 1;
+
+ static StandardResourceDescriptionResolver getResourceDescriptionResolver(final String... keyPrefix) {
+ StringBuilder prefix = new StringBuilder(SUBSYSTEM_NAME);
+ for (String kp : keyPrefix) {
+ prefix.append('.').append(kp);
+ }
+ return new StandardResourceDescriptionResolver(prefix.toString(), RESOURCE_NAME, KeycloakExtension.class.getClassLoader(), true, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void initializeParsers(final ExtensionParsingContext context) {
+ context.setSubsystemXmlMapping(SUBSYSTEM_NAME, NAMESPACE, PARSER);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void initialize(final ExtensionContext context) {
+ ROOT_LOGGER.debug("Activating Keycloak Extension");
+ final SubsystemRegistration subsystem = context.registerSubsystem(SUBSYSTEM_NAME, MGMT_API_VERSION_MAJOR, MGMT_API_VERSION_MINOR);
+
+ subsystem.registerSubsystemModel(KEYCLOAK_SUBSYSTEM_RESOURCE);
+ subsystem.registerXMLElementWriter(PARSER);
+ }
+}
diff --git a/integration/as7-eap6/as7-server-subsystem/src/main/java/org/keycloak/subsystem/server/as7/KeycloakSubsystemAdd.java b/integration/as7-eap6/as7-server-subsystem/src/main/java/org/keycloak/subsystem/server/as7/KeycloakSubsystemAdd.java
new file mode 100755
index 0000000..19d7aa2
--- /dev/null
+++ b/integration/as7-eap6/as7-server-subsystem/src/main/java/org/keycloak/subsystem/server/as7/KeycloakSubsystemAdd.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.keycloak.subsystem.server.as7;
+
+import org.jboss.as.controller.AbstractBoottimeAddStepHandler;
+import org.jboss.as.controller.AttributeDefinition;
+import org.jboss.as.controller.OperationContext;
+import org.jboss.as.controller.OperationFailedException;
+import org.jboss.as.controller.ServiceVerificationHandler;
+import org.jboss.as.controller.registry.Resource;
+import org.jboss.as.server.AbstractDeploymentChainStep;
+import org.jboss.as.server.DeploymentProcessorTarget;
+import org.jboss.as.server.deployment.Phase;
+import org.jboss.dmr.ModelNode;
+
+import org.jboss.msc.service.ServiceController;
+
+import java.util.List;
+
+import static org.keycloak.subsystem.server.as7.KeycloakExtension.SUBSYSTEM_NAME;
+
+/**
+ * The Keycloak subsystem add update handler.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
+ */
+class KeycloakSubsystemAdd extends AbstractBoottimeAddStepHandler {
+
+ static final KeycloakSubsystemAdd INSTANCE = new KeycloakSubsystemAdd();
+
+ @Override
+ protected void performBoottime(final OperationContext context, final ModelNode operation, final ModelNode model, ServiceVerificationHandler verificationHandler, List<ServiceController<?>> newControllers) {
+ context.addStep(new AbstractDeploymentChainStep() {
+ @Override
+ protected void execute(DeploymentProcessorTarget processorTarget) {
+ processorTarget.addDeploymentProcessor(SUBSYSTEM_NAME,
+ Phase.POST_MODULE, // PHASE
+ Phase.POST_MODULE_VALIDATOR_FACTORY - 1, // PRIORITY
+ new KeycloakServerDeploymentProcessor());
+ }
+ }, OperationContext.Stage.RUNTIME);
+ }
+
+ protected void populateModel(final OperationContext context, final ModelNode operation, final Resource resource) throws OperationFailedException {
+ ModelNode model = resource.getModel();
+
+ // set attribute values from parsed model
+ for (AttributeDefinition attrDef : KeycloakSubsystemDefinition.ALL_ATTRIBUTES) {
+ attrDef.validateAndSet(operation, model);
+ }
+
+ // returns early if on domain controller
+ if (!requiresRuntime(context)) {
+ return;
+ }
+
+ // don't want to try to start server on host controller
+ if (!context.isNormalServer()) {
+ return;
+ }
+
+ ModelNode webContextNode = resource.getModel().get(KeycloakSubsystemDefinition.WEB_CONTEXT.getName());
+ if (!webContextNode.isDefined()) {
+ webContextNode = KeycloakSubsystemDefinition.WEB_CONTEXT.getDefaultValue();
+ }
+ String webContext = webContextNode.asString();
+
+ ServerUtil serverUtil = new ServerUtil(operation);
+ serverUtil.addStepToUploadServerWar(context);
+ KeycloakAdapterConfigService.INSTANCE.setWebContext(webContext);
+ }
+}
diff --git a/integration/as7-eap6/as7-server-subsystem/src/main/java/org/keycloak/subsystem/server/as7/KeycloakSubsystemParser.java b/integration/as7-eap6/as7-server-subsystem/src/main/java/org/keycloak/subsystem/server/as7/KeycloakSubsystemParser.java
new file mode 100755
index 0000000..05bd553
--- /dev/null
+++ b/integration/as7-eap6/as7-server-subsystem/src/main/java/org/keycloak/subsystem/server/as7/KeycloakSubsystemParser.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2014 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.keycloak.subsystem.server.as7;
+
+import org.jboss.as.controller.PathAddress;
+import org.jboss.as.controller.operations.common.Util;
+import org.jboss.as.controller.parsing.ParseUtils;
+import org.jboss.as.controller.persistence.SubsystemMarshallingContext;
+import org.jboss.dmr.ModelNode;
+import org.jboss.staxmapper.XMLElementReader;
+import org.jboss.staxmapper.XMLElementWriter;
+import org.jboss.staxmapper.XMLExtendedStreamReader;
+import org.jboss.staxmapper.XMLExtendedStreamWriter;
+
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import java.util.List;
+
+import static org.keycloak.subsystem.server.as7.KeycloakExtension.PATH_SUBSYSTEM;
+import static org.keycloak.subsystem.server.as7.KeycloakSubsystemDefinition.WEB_CONTEXT;
+
+/**
+ * The subsystem parser, which uses stax to read and write to and from xml
+ */
+class KeycloakSubsystemParser implements XMLStreamConstants, XMLElementReader<List<ModelNode>>, XMLElementWriter<SubsystemMarshallingContext> {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void readElement(final XMLExtendedStreamReader reader, final List<ModelNode> list) throws XMLStreamException {
+ // Require no attributes
+ ParseUtils.requireNoAttributes(reader);
+ ModelNode addKeycloakSub = Util.createAddOperation(PathAddress.pathAddress(PATH_SUBSYSTEM));
+ list.add(addKeycloakSub);
+
+ while (reader.hasNext() && nextTag(reader) != END_ELEMENT) {
+ if (reader.getLocalName().equals(WEB_CONTEXT.getXmlName())) {
+ WEB_CONTEXT.parseAndSetParameter(reader.getElementText(), addKeycloakSub, reader);
+ } else {
+ throw new XMLStreamException("Unknown keycloak-server subsystem tag: " + reader.getLocalName());
+ }
+ }
+ }
+
+ // used for debugging
+ private int nextTag(XMLExtendedStreamReader reader) throws XMLStreamException {
+ return reader.nextTag();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void writeContent(final XMLExtendedStreamWriter writer, final SubsystemMarshallingContext context) throws XMLStreamException {
+ context.startSubsystemElement(KeycloakExtension.NAMESPACE, false);
+ writeWebContext(writer, context);
+ writer.writeEndElement();
+ }
+
+ private void writeWebContext(XMLExtendedStreamWriter writer, SubsystemMarshallingContext context) throws XMLStreamException {
+ if (!context.getModelNode().get(WEB_CONTEXT.getName()).isDefined()) {
+ return;
+ }
+
+ WEB_CONTEXT.marshallAsElement(context.getModelNode(), writer);
+ }
+}
diff --git a/integration/as7-eap6/as7-server-subsystem/src/main/resources/META-INF/services/org.jboss.as.controller.Extension b/integration/as7-eap6/as7-server-subsystem/src/main/resources/META-INF/services/org.jboss.as.controller.Extension
new file mode 100644
index 0000000..e69bf09
--- /dev/null
+++ b/integration/as7-eap6/as7-server-subsystem/src/main/resources/META-INF/services/org.jboss.as.controller.Extension
@@ -0,0 +1 @@
+org.keycloak.subsystem.server.as7.KeycloakExtension
diff --git a/integration/as7-eap6/as7-server-subsystem/src/main/resources/org/keycloak/subsystem/server/as7/LocalDescriptions.properties b/integration/as7-eap6/as7-server-subsystem/src/main/resources/org/keycloak/subsystem/server/as7/LocalDescriptions.properties
new file mode 100755
index 0000000..909e6b3
--- /dev/null
+++ b/integration/as7-eap6/as7-server-subsystem/src/main/resources/org/keycloak/subsystem/server/as7/LocalDescriptions.properties
@@ -0,0 +1,4 @@
+keycloak-server.subsystem=Keycloak subsystem
+keycloak-server.subsystem.add=Operation Adds Keycloak subsystem
+keycloak-server.subsystem.remove=Operation removes Keycloak subsystem
+keycloak-server.subsystem.web-context=Web context where Keycloak server is bound. Default value is 'auth'.
diff --git a/integration/as7-eap6/as7-subsystem/pom.xml b/integration/as7-eap6/as7-subsystem/pom.xml
index a186da3..9e92289 100755
--- a/integration/as7-eap6/as7-subsystem/pom.xml
+++ b/integration/as7-eap6/as7-subsystem/pom.xml
@@ -20,7 +20,7 @@
<parent>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-parent</artifactId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
integration/as7-eap6/pom.xml 3(+2 -1)
diff --git a/integration/as7-eap6/pom.xml b/integration/as7-eap6/pom.xml
index 9917521..de84c4e 100644
--- a/integration/as7-eap6/pom.xml
+++ b/integration/as7-eap6/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<name>Keycloak AS7 / JBoss EAP 6 Integration</name>
@@ -16,5 +16,6 @@
<modules>
<module>as7-adapter</module>
<module>as7-subsystem</module>
+ <module>as7-server-subsystem</module>
</modules>
</project>
\ No newline at end of file
integration/installed/pom.xml 2(+1 -1)
diff --git a/integration/installed/pom.xml b/integration/installed/pom.xml
index 034c897..529b99f 100755
--- a/integration/installed/pom.xml
+++ b/integration/installed/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/integration/jaxrs-oauth-client/pom.xml b/integration/jaxrs-oauth-client/pom.xml
index e12f4d1..fbda50c 100755
--- a/integration/jaxrs-oauth-client/pom.xml
+++ b/integration/jaxrs-oauth-client/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -17,16 +17,13 @@
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>jaxrs-api</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.jboss.resteasy</groupId>
- <artifactId>resteasy-jaxrs</artifactId>
+ <version>${resteasy.latest.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
+ <version>${resteasy.latest.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
diff --git a/integration/jboss-adapter-core/pom.xml b/integration/jboss-adapter-core/pom.xml
index 0e919ec..0e6cb1e 100755
--- a/integration/jboss-adapter-core/pom.xml
+++ b/integration/jboss-adapter-core/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
integration/jetty/jetty8.1/pom.xml 2(+1 -1)
diff --git a/integration/jetty/jetty8.1/pom.xml b/integration/jetty/jetty8.1/pom.xml
index de8ac85..a6d49d7 100755
--- a/integration/jetty/jetty8.1/pom.xml
+++ b/integration/jetty/jetty8.1/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
integration/jetty/jetty9.1/pom.xml 2(+1 -1)
diff --git a/integration/jetty/jetty9.1/pom.xml b/integration/jetty/jetty9.1/pom.xml
index b10db5f..27e7c06 100755
--- a/integration/jetty/jetty9.1/pom.xml
+++ b/integration/jetty/jetty9.1/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
integration/jetty/jetty9.2/pom.xml 2(+1 -1)
diff --git a/integration/jetty/jetty9.2/pom.xml b/integration/jetty/jetty9.2/pom.xml
index 700172a..13104d5 100755
--- a/integration/jetty/jetty9.2/pom.xml
+++ b/integration/jetty/jetty9.2/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
integration/jetty/jetty-core/pom.xml 2(+1 -1)
diff --git a/integration/jetty/jetty-core/pom.xml b/integration/jetty/jetty-core/pom.xml
index 9c48413..1919434 100755
--- a/integration/jetty/jetty-core/pom.xml
+++ b/integration/jetty/jetty-core/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
integration/jetty/pom.xml 2(+1 -1)
diff --git a/integration/jetty/pom.xml b/integration/jetty/pom.xml
index c8ca65e..c3eb1f3 100755
--- a/integration/jetty/pom.xml
+++ b/integration/jetty/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<name>Keycloak Jetty Integration</name>
integration/js/pom.xml 2(+1 -1)
diff --git a/integration/js/pom.xml b/integration/js/pom.xml
index 2e3d13c..a3c747b 100755
--- a/integration/js/pom.xml
+++ b/integration/js/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
integration/osgi-adapter/pom.xml 2(+1 -1)
diff --git a/integration/osgi-adapter/pom.xml b/integration/osgi-adapter/pom.xml
index 045966e..5aa76b5 100755
--- a/integration/osgi-adapter/pom.xml
+++ b/integration/osgi-adapter/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
integration/pom.xml 2(+1 -1)
diff --git a/integration/pom.xml b/integration/pom.xml
index 0a0f4a5..a7c8675 100755
--- a/integration/pom.xml
+++ b/integration/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<name>Keycloak Integration</name>
diff --git a/integration/servlet-oauth-client/pom.xml b/integration/servlet-oauth-client/pom.xml
index 7df8cbe..983ccff 100755
--- a/integration/servlet-oauth-client/pom.xml
+++ b/integration/servlet-oauth-client/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
integration/spring-boot/pom.xml 2(+1 -1)
diff --git a/integration/spring-boot/pom.xml b/integration/spring-boot/pom.xml
index 26296e8..ef31e98 100755
--- a/integration/spring-boot/pom.xml
+++ b/integration/spring-boot/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
integration/spring-security/pom.xml 2(+1 -1)
diff --git a/integration/spring-security/pom.xml b/integration/spring-security/pom.xml
index 9bd7ae4..9439453 100755
--- a/integration/spring-security/pom.xml
+++ b/integration/spring-security/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandler.java b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandler.java
index 6a64765..d843aa7 100644
--- a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandler.java
+++ b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandler.java
@@ -6,15 +6,12 @@ import org.keycloak.adapters.springsecurity.AdapterDeploymentContextBean;
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.util.Assert;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
/**
* Logs the current user out of Keycloak.
@@ -36,29 +33,17 @@ public class KeycloakLogoutHandler implements LogoutHandler {
@Override
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
- if (authentication instanceof AnonymousAuthenticationToken) {
- log.warn("Attempt to log out an anonymous authentication");
+ if (!KeycloakAuthenticationToken.class.isAssignableFrom(authentication.getClass())) {
+ log.warn("Cannot log out a non-Keycloak authentication: {}", authentication);
return;
}
- try {
- handleSingleSignOut(request, response);
- } catch (IOException e) {
- throw new IllegalStateException("Unable to make logout admin request!", e);
- }
-
+ handleSingleSignOut(request, response, (KeycloakAuthenticationToken) authentication);
}
- protected void handleSingleSignOut(HttpServletRequest request, HttpServletResponse response) throws IOException {
-
- KeycloakAuthenticationToken authentication = (KeycloakAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
+ protected void handleSingleSignOut(HttpServletRequest request, HttpServletResponse response, KeycloakAuthenticationToken authenticationToken) {
KeycloakDeployment deployment = deploymentContextBean.getDeployment();
- RefreshableKeycloakSecurityContext session = (RefreshableKeycloakSecurityContext) authentication.getAccount().getKeycloakSecurityContext();
-
- try {
- session.logout(deployment);
- } catch (Exception e) {
- log.error("Unable to complete Keycloak single sign out", e);
- }
+ RefreshableKeycloakSecurityContext session = (RefreshableKeycloakSecurityContext) authenticationToken.getAccount().getKeycloakSecurityContext();
+ session.logout(deployment);
}
}
diff --git a/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandlerTest.java b/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandlerTest.java
new file mode 100644
index 0000000..2ee32af
--- /dev/null
+++ b/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandlerTest.java
@@ -0,0 +1,96 @@
+package org.keycloak.adapters.springsecurity.authentication;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.keycloak.adapters.KeycloakAccount;
+import org.keycloak.adapters.KeycloakDeployment;
+import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
+import org.keycloak.adapters.springsecurity.AdapterDeploymentContextBean;
+import org.keycloak.adapters.springsecurity.account.KeycloakRole;
+import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.security.authentication.AnonymousAuthenticationToken;
+import org.springframework.security.authentication.RememberMeAuthenticationToken;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.UUID;
+
+import static org.mockito.Mockito.*;
+
+/**
+ * Keycloak logout handler tests.
+ */
+public class KeycloakLogoutHandlerTest {
+
+ private KeycloakAuthenticationToken keycloakAuthenticationToken;
+ private KeycloakLogoutHandler keycloakLogoutHandler;
+
+ private MockHttpServletRequest request;
+ private MockHttpServletResponse response;
+
+ @Mock
+ private AdapterDeploymentContextBean adapterDeploymentContextBean;
+
+ @Mock
+ private KeycloakAccount keycloakAccount;
+
+ @Mock
+ private KeycloakDeployment keycloakDeployment;
+
+ @Mock
+ private RefreshableKeycloakSecurityContext session;
+
+ private Collection<KeycloakRole> authorities = Collections.singleton(new KeycloakRole(UUID.randomUUID().toString()));
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ keycloakAuthenticationToken = mock(KeycloakAuthenticationToken.class);
+ keycloakLogoutHandler = new KeycloakLogoutHandler(adapterDeploymentContextBean);
+ request = new MockHttpServletRequest();
+ response = new MockHttpServletResponse();
+
+ when(adapterDeploymentContextBean.getDeployment()).thenReturn(keycloakDeployment);
+ when(keycloakAuthenticationToken.getAccount()).thenReturn(keycloakAccount);
+ when(keycloakAccount.getKeycloakSecurityContext()).thenReturn(session);
+ }
+
+ @Test
+ public void testLogout() throws Exception {
+ keycloakLogoutHandler.logout(request, response, keycloakAuthenticationToken);
+ verify(session).logout(eq(keycloakDeployment));
+ }
+
+ @Test
+ public void testLogoutAnonymousAuthentication() throws Exception {
+ Authentication authentication = new AnonymousAuthenticationToken(UUID.randomUUID().toString(), UUID.randomUUID().toString(), authorities);
+ keycloakLogoutHandler.logout(request, response, authentication);
+ verifyZeroInteractions(session);
+ }
+
+ @Test
+ public void testLogoutUsernamePasswordAuthentication() throws Exception {
+ Authentication authentication = new UsernamePasswordAuthenticationToken(UUID.randomUUID().toString(), UUID.randomUUID().toString(), authorities);
+ keycloakLogoutHandler.logout(request, response, authentication);
+ verifyZeroInteractions(session);
+ }
+
+ @Test
+ public void testLogoutRememberMeAuthentication() throws Exception {
+ Authentication authentication = new RememberMeAuthenticationToken(UUID.randomUUID().toString(), UUID.randomUUID().toString(), authorities);
+ keycloakLogoutHandler.logout(request, response, authentication);
+ verifyZeroInteractions(session);
+ }
+
+ @Test
+ public void testHandleSingleSignOut() throws Exception {
+ keycloakLogoutHandler.handleSingleSignOut(request, response, keycloakAuthenticationToken);
+ verify(session).logout(eq(keycloakDeployment));
+ }
+}
integration/tomcat/pom.xml 2(+1 -1)
diff --git a/integration/tomcat/pom.xml b/integration/tomcat/pom.xml
index e267cbd..36b8f68 100755
--- a/integration/tomcat/pom.xml
+++ b/integration/tomcat/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<name>Keycloak Tomcat Integration</name>
integration/tomcat/tomcat6/pom.xml 2(+1 -1)
diff --git a/integration/tomcat/tomcat6/pom.xml b/integration/tomcat/tomcat6/pom.xml
index bba65d2..fcfcfde 100755
--- a/integration/tomcat/tomcat6/pom.xml
+++ b/integration/tomcat/tomcat6/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
integration/tomcat/tomcat7/pom.xml 2(+1 -1)
diff --git a/integration/tomcat/tomcat7/pom.xml b/integration/tomcat/tomcat7/pom.xml
index bf5009a..7a8e8b4 100755
--- a/integration/tomcat/tomcat7/pom.xml
+++ b/integration/tomcat/tomcat7/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
integration/tomcat/tomcat8/pom.xml 15(+1 -14)
diff --git a/integration/tomcat/tomcat8/pom.xml b/integration/tomcat/tomcat8/pom.xml
index 678f02a..59b5729 100755
--- a/integration/tomcat/tomcat8/pom.xml
+++ b/integration/tomcat/tomcat8/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -86,19 +86,6 @@
<artifactId>jackson-xc</artifactId>
</dependency>
<dependency>
- <groupId>org.apache.tomcat</groupId>
- <artifactId>tomcat-servlet-api</artifactId>
- <version>${tomcat.version}</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.tomcat</groupId>
- <artifactId>tomcat-catalina</artifactId>
- <version>${tomcat.version}</version>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
diff --git a/integration/tomcat/tomcat-core/pom.xml b/integration/tomcat/tomcat-core/pom.xml
index b96aed0..81fdbb0 100755
--- a/integration/tomcat/tomcat-core/pom.xml
+++ b/integration/tomcat/tomcat-core/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
integration/undertow/pom.xml 2(+1 -1)
diff --git a/integration/undertow/pom.xml b/integration/undertow/pom.xml
index 83ea952..0a4d3c1 100755
--- a/integration/undertow/pom.xml
+++ b/integration/undertow/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
integration/wildfly/pom.xml 4(+2 -2)
diff --git a/integration/wildfly/pom.xml b/integration/wildfly/pom.xml
index 588bf10..598fee3 100644
--- a/integration/wildfly/pom.xml
+++ b/integration/wildfly/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<name>Keycloak WildFly Integration</name>
@@ -16,8 +16,8 @@
<modules>
<module>wildfly-adapter</module>
<module>wildfly-extensions</module>
- <module>wildfly-server-subsystem</module>
<module>wf8-subsystem</module>
<module>wf9-subsystem</module>
+ <module>wf9-server-subsystem</module>
</modules>
</project>
\ No newline at end of file
diff --git a/integration/wildfly/wf8-subsystem/pom.xml b/integration/wildfly/wf8-subsystem/pom.xml
index 8036cd8..804963e 100755
--- a/integration/wildfly/wf8-subsystem/pom.xml
+++ b/integration/wildfly/wf8-subsystem/pom.xml
@@ -20,7 +20,7 @@
<parent>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-parent</artifactId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
diff --git a/integration/wildfly/wf9-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemRemoveHandler.java b/integration/wildfly/wf9-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemRemoveHandler.java
new file mode 100644
index 0000000..4a1bdfc
--- /dev/null
+++ b/integration/wildfly/wf9-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemRemoveHandler.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2014 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.keycloak.subsystem.server.extension;
+
+import org.jboss.as.controller.OperationContext;
+import org.jboss.as.controller.OperationFailedException;
+import org.jboss.as.controller.OperationStepHandler;
+import org.jboss.as.controller.PathAddress;
+import org.jboss.as.controller.PathElement;
+import org.jboss.as.controller.ReloadRequiredRemoveStepHandler;
+import org.jboss.as.controller.operations.common.Util;
+import org.jboss.dmr.ModelNode;
+
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.DEPLOYMENT;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.REMOVE;
+import org.jboss.as.controller.registry.ImmutableManagementResourceRegistration;
+
+/**
+ * Remove an auth-server from a realm.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2014 Red Hat Inc.
+ */
+public final class KeycloakSubsystemRemoveHandler extends ReloadRequiredRemoveStepHandler {
+
+ static KeycloakSubsystemRemoveHandler INSTANCE = new KeycloakSubsystemRemoveHandler();
+
+ private KeycloakSubsystemRemoveHandler() {}
+
+ @Override
+ protected void performRemove(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException {
+ String deploymentName = ServerUtil.getDeploymentName(operation);
+ KeycloakAdapterConfigService.INSTANCE.setWebContext(null);
+
+ if (requiresRuntime(context)) { // don't do this on a domain controller
+ addStepToRemoveServerWar(context, deploymentName);
+ }
+
+ super.performRemove(context, operation, model);
+ }
+
+ private void addStepToRemoveServerWar(OperationContext context, String deploymentName) {
+ PathAddress deploymentAddress = PathAddress.pathAddress(PathElement.pathElement(DEPLOYMENT, deploymentName));
+ ModelNode op = Util.createOperation(REMOVE, deploymentAddress);
+ context.addStep(op, getRemoveHandler(context, deploymentAddress), OperationContext.Stage.MODEL);
+ }
+
+ private OperationStepHandler getRemoveHandler(OperationContext context, PathAddress address) {
+ ImmutableManagementResourceRegistration rootResourceRegistration = context.getRootResourceRegistration();
+ return rootResourceRegistration.getOperationHandler(address, REMOVE);
+ }
+}
diff --git a/integration/wildfly/wf9-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemWriteAttributeHandler.java b/integration/wildfly/wf9-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemWriteAttributeHandler.java
new file mode 100755
index 0000000..ecba429
--- /dev/null
+++ b/integration/wildfly/wf9-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemWriteAttributeHandler.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2014 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.keycloak.subsystem.server.extension;
+
+import org.jboss.as.controller.AttributeDefinition;
+import org.jboss.as.controller.SimpleAttributeDefinition;
+
+import java.util.List;
+import org.jboss.as.controller.ModelOnlyWriteAttributeHandler;
+import org.jboss.as.controller.OperationContext;
+import org.jboss.as.controller.OperationFailedException;
+import org.jboss.as.controller.registry.Resource;
+import org.jboss.dmr.ModelNode;
+
+/**
+ * Update an attribute on an Auth Server.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2014 Red Hat Inc.
+ */
+public class KeycloakSubsystemWriteAttributeHandler extends ModelOnlyWriteAttributeHandler { //extends ReloadRequiredWriteAttributeHandler {
+
+ public KeycloakSubsystemWriteAttributeHandler(List<SimpleAttributeDefinition> definitions) {
+ this(definitions.toArray(new AttributeDefinition[definitions.size()]));
+ }
+
+ public KeycloakSubsystemWriteAttributeHandler(AttributeDefinition... definitions) {
+ super(definitions);
+ }
+
+ @Override
+ protected void finishModelStage(OperationContext context, ModelNode operation, String attributeName, ModelNode newValue, ModelNode oldValue, Resource model) throws OperationFailedException {
+ if (!context.isNormalServer() || attribNotChanging(attributeName, newValue, oldValue)) {
+ super.finishModelStage(context, operation, attributeName, newValue, oldValue, model);
+ return;
+ }
+
+ String deploymentName = ServerUtil.getDeploymentName(operation);
+
+ if (attributeName.equals(KeycloakSubsystemDefinition.WEB_CONTEXT.getName())) {
+ KeycloakAdapterConfigService.INSTANCE.setWebContext(newValue.asString());
+ ServerUtil.addStepToRedeployServerWar(context, deploymentName);
+ }
+
+ super.finishModelStage(context, operation, attributeName, newValue, oldValue, model);
+ }
+
+ private boolean attribNotChanging(String attributeName, ModelNode newValue, ModelNode oldValue) {
+ SimpleAttributeDefinition attribDef = KeycloakSubsystemDefinition.lookup(attributeName);
+ if (!oldValue.isDefined()) {
+ oldValue = attribDef.getDefaultValue();
+ }
+ if (!newValue.isDefined()) {
+ newValue = attribDef.getDefaultValue();
+ }
+ return newValue.equals(oldValue);
+ }
+}
diff --git a/integration/wildfly/wf9-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/ServerUtil.java b/integration/wildfly/wf9-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/ServerUtil.java
new file mode 100644
index 0000000..2911afe
--- /dev/null
+++ b/integration/wildfly/wf9-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/ServerUtil.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2014 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.keycloak.subsystem.server.extension;
+
+import java.io.File;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import org.jboss.as.controller.OperationContext;
+import org.jboss.as.controller.OperationFailedException;
+import org.jboss.as.controller.OperationStepHandler;
+import org.jboss.as.controller.PathAddress;
+import org.jboss.as.controller.PathElement;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADD;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADDRESS;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ARCHIVE;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.CONTENT;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.DEPLOYMENT;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ENABLED;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.PERSISTENT;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.PATH;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.REDEPLOY;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.RUNTIME_NAME;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.URL;
+import org.jboss.as.controller.operations.common.Util;
+import org.jboss.as.controller.registry.ImmutableManagementResourceRegistration;
+
+import org.jboss.dmr.ModelNode;
+import org.jboss.modules.Module;
+import org.jboss.modules.ModuleIdentifier;
+import org.jboss.modules.ModuleLoadException;
+
+/**
+ * Utility methods that help assemble and start an auth server.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2014 Red Hat Inc.
+ */
+public class ServerUtil {
+
+ private static final ModuleIdentifier KEYCLOAK_SUBSYSTEM = ModuleIdentifier.create("org.keycloak.keycloak-server-subsystem");
+
+ private final String deploymentName;
+ private final Module subsysModule;
+ private final String keycloakVersion;
+ private final boolean isServerWarExploded;
+ private final URI serverWar;
+
+ ServerUtil(ModelNode operation) {
+ this.deploymentName = getDeploymentName(operation);
+ this.subsysModule = findSubsysModule();
+ this.keycloakVersion = subsysModule.getProperty("keycloak-version");
+ this.isServerWarExploded = Boolean.parseBoolean(subsysModule.getProperty("server-war-exploded"));
+ this.serverWar = findServerWarUri();
+ }
+
+ private Module findSubsysModule() {
+ try {
+ return Module.getModuleFromCallerModuleLoader(KEYCLOAK_SUBSYSTEM);
+ } catch (ModuleLoadException e) {
+ throw new IllegalStateException("Can't find Keycloak subsystem.", e);
+ }
+ }
+
+ private URI findServerWarUri() throws IllegalStateException {
+ try {
+ URL subsysResource = this.subsysModule.getExportedResource("module.xml");
+ File subsysDir = new File(subsysResource.toURI()).getParentFile();
+ File serverWarDir = new File(subsysDir, "server-war");
+ if (this.isServerWarExploded) {
+ return serverWarDir.toURI();
+ } else {
+ return new File(serverWarDir, "keycloak-server-" + keycloakVersion + ".war").toURI();
+ }
+ } catch (URISyntaxException e) {
+ throw new IllegalStateException(e);
+ } catch (IllegalArgumentException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ void addStepToUploadServerWar(OperationContext context) throws OperationFailedException {
+ PathAddress deploymentAddress = deploymentAddress(deploymentName);
+ ModelNode op = Util.createOperation(ADD, deploymentAddress);
+
+ // this is required for deployment to take place
+ op.get(ENABLED).set(true);
+
+ // prevents writing this deployment out to standalone.xml
+ op.get(PERSISTENT).set(false);
+
+ // Owner attribute is valid starting with WidlFly 9. Ignored in WildFly 8
+ op.get("owner").set(new ModelNode().add("subsystem", KeycloakExtension.SUBSYSTEM_NAME));
+
+ if (serverWar == null) {
+ throw new OperationFailedException("Keycloak Server WAR not found in keycloak-server-subsystem module");
+ }
+
+ op.get(CONTENT).add(makeContentItem());
+
+ context.addStep(op, getHandler(context, deploymentAddress, ADD), OperationContext.Stage.MODEL);
+ }
+
+ private ModelNode makeContentItem() throws OperationFailedException {
+ ModelNode contentItem = new ModelNode();
+
+ if (this.isServerWarExploded) {
+ String urlString = new File(serverWar).getAbsolutePath();
+ contentItem.get(PATH).set(urlString);
+ contentItem.get(ARCHIVE).set(false);
+ } else {
+ String urlString = serverWar.toString();
+ contentItem.get(URL).set(urlString);
+ }
+
+ return contentItem;
+ }
+
+ static void addStepToRedeployServerWar(OperationContext context, String deploymentName) {
+ addDeploymentAction(context, REDEPLOY, deploymentName);
+ }
+
+ private static void addDeploymentAction(OperationContext context, String operation, String deploymentName) {
+ if (!context.isNormalServer()) {
+ return;
+ }
+ PathAddress deploymentAddress = deploymentAddress(deploymentName);
+ ModelNode op = Util.createOperation(operation, deploymentAddress);
+ op.get(RUNTIME_NAME).set(deploymentName);
+ context.addStep(op, getHandler(context, deploymentAddress, operation), OperationContext.Stage.MODEL);
+ }
+
+ private static PathAddress deploymentAddress(String deploymentName) {
+ return PathAddress.pathAddress(PathElement.pathElement(DEPLOYMENT, deploymentName));
+ }
+
+ static OperationStepHandler getHandler(OperationContext context, PathAddress address, String opName) {
+ ImmutableManagementResourceRegistration rootResourceRegistration = context.getRootResourceRegistration();
+ return rootResourceRegistration.getOperationHandler(address, opName);
+ }
+
+ static String getDeploymentName(ModelNode operation) {
+ String deploymentName = Util.getNameFromAddress(operation.get(ADDRESS));
+ if (!deploymentName.toLowerCase().endsWith(".war")) {
+ deploymentName += ".war";
+ }
+
+ return deploymentName;
+ }
+}
diff --git a/integration/wildfly/wf9-server-subsystem/src/main/java/org/keycloak/subsystem/server/logging/KeycloakLogger.java b/integration/wildfly/wf9-server-subsystem/src/main/java/org/keycloak/subsystem/server/logging/KeycloakLogger.java
new file mode 100755
index 0000000..bf6053b
--- /dev/null
+++ b/integration/wildfly/wf9-server-subsystem/src/main/java/org/keycloak/subsystem/server/logging/KeycloakLogger.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.keycloak.subsystem.server.logging;
+
+import org.jboss.logging.BasicLogger;
+import org.jboss.logging.Logger;
+import org.jboss.logging.annotations.LogMessage;
+import org.jboss.logging.annotations.Message;
+import org.jboss.logging.annotations.MessageLogger;
+
+import static org.jboss.logging.Logger.Level.INFO;
+
+/**
+ * This interface to be fleshed out later when error messages are fully externalized.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
+ */
+@MessageLogger(projectCode = "KEYCLOAK")
+public interface KeycloakLogger extends BasicLogger {
+
+ /**
+ * A logger with a category of the package name.
+ */
+ KeycloakLogger ROOT_LOGGER = Logger.getMessageLogger(KeycloakLogger.class, "org.jboss.keycloak");
+}
diff --git a/integration/wildfly/wf9-server-subsystem/src/main/java/org/keycloak/subsystem/server/logging/KeycloakMessages.java b/integration/wildfly/wf9-server-subsystem/src/main/java/org/keycloak/subsystem/server/logging/KeycloakMessages.java
new file mode 100755
index 0000000..710c054
--- /dev/null
+++ b/integration/wildfly/wf9-server-subsystem/src/main/java/org/keycloak/subsystem/server/logging/KeycloakMessages.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.keycloak.subsystem.server.logging;
+
+import org.jboss.logging.Messages;
+import org.jboss.logging.annotations.MessageBundle;
+
+/**
+ * This interface to be fleshed out later when error messages are fully externalized.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2012 Red Hat Inc.
+ */
+@MessageBundle(projectCode = "KEYCLOAK")
+public interface KeycloakMessages {
+
+ /**
+ * The messages
+ */
+ KeycloakMessages MESSAGES = Messages.getBundle(KeycloakMessages.class);
+}
diff --git a/integration/wildfly/wf9-server-subsystem/src/main/resources/org/keycloak/subsystem/server/extension/LocalDescriptions.properties b/integration/wildfly/wf9-server-subsystem/src/main/resources/org/keycloak/subsystem/server/extension/LocalDescriptions.properties
new file mode 100755
index 0000000..909e6b3
--- /dev/null
+++ b/integration/wildfly/wf9-server-subsystem/src/main/resources/org/keycloak/subsystem/server/extension/LocalDescriptions.properties
@@ -0,0 +1,4 @@
+keycloak-server.subsystem=Keycloak subsystem
+keycloak-server.subsystem.add=Operation Adds Keycloak subsystem
+keycloak-server.subsystem.remove=Operation removes Keycloak subsystem
+keycloak-server.subsystem.web-context=Web context where Keycloak server is bound. Default value is 'auth'.
diff --git a/integration/wildfly/wf9-server-subsystem/src/main/resources/schema/wildfly-keycloak-server_1_1.xsd b/integration/wildfly/wf9-server-subsystem/src/main/resources/schema/wildfly-keycloak-server_1_1.xsd
new file mode 100755
index 0000000..b346d36
--- /dev/null
+++ b/integration/wildfly/wf9-server-subsystem/src/main/resources/schema/wildfly-keycloak-server_1_1.xsd
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="urn:jboss:domain:keycloak-server:1.1"
+ xmlns="urn:jboss:domain:keycloak-server:1.1"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified"
+ version="1.0">
+
+ <!-- The subsystem root element -->
+ <xs:element name="subsystem" type="subsystem-type"/>
+
+ <xs:complexType name="subsystem-type">
+ <xs:annotation>
+ <xs:documentation>
+ <![CDATA[
+ The Keycloak server subsystem, used to configure the Keycloak server
+ ]]>
+ </xs:documentation>
+ </xs:annotation>
+ <xs:choice minOccurs="0" maxOccurs="1">
+ <xs:element name="web-context" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ </xs:choice>
+ </xs:complexType>
+</xs:schema>
diff --git a/integration/wildfly/wf9-server-subsystem/src/main/resources/subsystem-templates/keycloak-datasources.xml b/integration/wildfly/wf9-server-subsystem/src/main/resources/subsystem-templates/keycloak-datasources.xml
new file mode 100644
index 0000000..114545f
--- /dev/null
+++ b/integration/wildfly/wf9-server-subsystem/src/main/resources/subsystem-templates/keycloak-datasources.xml
@@ -0,0 +1,22 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- See src/resources/configuration/ReadMe.txt for how the configuration assembly works -->
+<config>
+ <extension-module>org.jboss.as.connector</extension-module>
+ <subsystem xmlns="urn:jboss:domain:datasources:3.0">
+ <datasources>
+ <datasource jndi-name="java:jboss/datasources/KeycloakDS" pool-name="KeycloakDS" enabled="true" use-java-context="true">
+ <connection-url>jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE</connection-url>
+ <driver>h2</driver>
+ <security>
+ <user-name>sa</user-name>
+ <password>sa</password>
+ </security>
+ </datasource>
+ <drivers>
+ <driver name="h2" module="com.h2database.h2">
+ <xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
+ </driver>
+ </drivers>
+ </datasources>
+ </subsystem>
+</config>
diff --git a/integration/wildfly/wf9-server-subsystem/src/main/resources/subsystem-templates/keycloak-server.xml b/integration/wildfly/wf9-server-subsystem/src/main/resources/subsystem-templates/keycloak-server.xml
new file mode 100644
index 0000000..4a83086
--- /dev/null
+++ b/integration/wildfly/wf9-server-subsystem/src/main/resources/subsystem-templates/keycloak-server.xml
@@ -0,0 +1,8 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Template used by WildFly build when directed to include Keycloak subsystem in a configuration. -->
+<config>
+ <extension-module>org.keycloak.keycloak-server-subsystem</extension-module>
+ <subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
+ <web-context>auth</web-context>
+ </subsystem>
+</config>
diff --git a/integration/wildfly/wf9-server-subsystem/src/test/resources/org/keycloak/subsystem/server/extension/keycloak-server-1.1.xml b/integration/wildfly/wf9-server-subsystem/src/test/resources/org/keycloak/subsystem/server/extension/keycloak-server-1.1.xml
new file mode 100644
index 0000000..bc8f11a
--- /dev/null
+++ b/integration/wildfly/wf9-server-subsystem/src/test/resources/org/keycloak/subsystem/server/extension/keycloak-server-1.1.xml
@@ -0,0 +1,3 @@
+<subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
+ <web-context>auth</web-context>
+</subsystem>
\ No newline at end of file
diff --git a/integration/wildfly/wf9-subsystem/pom.xml b/integration/wildfly/wf9-subsystem/pom.xml
index 8141b91..ef3f111 100755
--- a/integration/wildfly/wf9-subsystem/pom.xml
+++ b/integration/wildfly/wf9-subsystem/pom.xml
@@ -20,7 +20,7 @@
<parent>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-parent</artifactId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
diff --git a/integration/wildfly/wildfly-adapter/pom.xml b/integration/wildfly/wildfly-adapter/pom.xml
index 4c5ca3a..1248fd5 100755
--- a/integration/wildfly/wildfly-adapter/pom.xml
+++ b/integration/wildfly/wildfly-adapter/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/integration/wildfly/wildfly-extensions/pom.xml b/integration/wildfly/wildfly-extensions/pom.xml
index 30c3452..b25ce80 100755
--- a/integration/wildfly/wildfly-extensions/pom.xml
+++ b/integration/wildfly/wildfly-extensions/pom.xml
@@ -20,7 +20,7 @@
<parent>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-parent</artifactId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
model/api/pom.xml 2(+1 -1)
diff --git a/model/api/pom.xml b/model/api/pom.xml
index ec4325f..9cdefbb 100755
--- a/model/api/pom.xml
+++ b/model/api/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/model/api/src/main/java/org/keycloak/migration/MigrationModel.java b/model/api/src/main/java/org/keycloak/migration/MigrationModel.java
index 936fbcf..df24b3d 100755
--- a/model/api/src/main/java/org/keycloak/migration/MigrationModel.java
+++ b/model/api/src/main/java/org/keycloak/migration/MigrationModel.java
@@ -11,7 +11,7 @@ public interface MigrationModel {
/**
* Must have the form of major.minor.micro as the version is parsed and numbers are compared
*/
- public static final String LATEST_VERSION = "1.2.0.CR1";
+ public static final String LATEST_VERSION = "1.3.0.Beta1";
String getStoredVersion();
void setStoredVersion(String version);
diff --git a/model/api/src/main/java/org/keycloak/migration/MigrationModelManager.java b/model/api/src/main/java/org/keycloak/migration/MigrationModelManager.java
index 7f52ab3..722bc5e 100755
--- a/model/api/src/main/java/org/keycloak/migration/MigrationModelManager.java
+++ b/model/api/src/main/java/org/keycloak/migration/MigrationModelManager.java
@@ -1,7 +1,7 @@
package org.keycloak.migration;
import org.jboss.logging.Logger;
-import org.keycloak.migration.migrators.MigrateTo1_3_0_Beta1;
+import org.keycloak.migration.migrators.MigrateTo1_3_0;
import org.keycloak.migration.migrators.MigrationTo1_2_0_CR1;
import org.keycloak.models.KeycloakSession;
@@ -17,19 +17,21 @@ public class MigrationModelManager {
String storedVersion = model.getStoredVersion();
if (MigrationModel.LATEST_VERSION.equals(storedVersion)) return;
ModelVersion stored = null;
- if (storedVersion != null) new ModelVersion(storedVersion);
+ if (storedVersion != null) {
+ stored = new ModelVersion(storedVersion);
+ }
if (stored == null || stored.lessThan(MigrationTo1_2_0_CR1.VERSION)) {
if (stored != null) {
- logger.debug("Migrating older model to 1.2.0.RC1 updates");
+ logger.debug("Migrating older model to 1.2.0.CR1 updates");
}
new MigrationTo1_2_0_CR1().migrate(session);
}
- if (stored == null || stored.lessThan(MigrateTo1_3_0_Beta1.VERSION)) {
+ if (stored == null || stored.lessThan(MigrateTo1_3_0.VERSION)) {
if (stored != null) {
- logger.debug("Migrating older model to 1.3.0.Beta1 updates");
+ logger.debug("Migrating older model to 1.3.0 updates");
}
- new MigrateTo1_3_0_Beta1().migrate(session);
+ new MigrateTo1_3_0().migrate(session);
}
model.setStoredVersion(MigrationModel.LATEST_VERSION);
diff --git a/model/api/src/main/java/org/keycloak/migration/migrators/MigrateTo1_3_0.java b/model/api/src/main/java/org/keycloak/migration/migrators/MigrateTo1_3_0.java
new file mode 100755
index 0000000..1b68528
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/migration/migrators/MigrateTo1_3_0.java
@@ -0,0 +1,84 @@
+package org.keycloak.migration.migrators;
+
+import org.keycloak.migration.ModelVersion;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.LDAPConstants;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserFederationEventAwareProviderFactory;
+import org.keycloak.models.UserFederationMapperModel;
+import org.keycloak.models.UserFederationProvider;
+import org.keycloak.models.UserFederationProviderFactory;
+import org.keycloak.models.UserFederationProviderModel;
+import org.keycloak.models.utils.DefaultAuthenticationFlows;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.naming.directory.SearchControls;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class MigrateTo1_3_0 {
+ public static final ModelVersion VERSION = new ModelVersion("1.3.0");
+
+
+ public void migrate(KeycloakSession session) {
+ List<RealmModel> realms = session.realms().getRealms();
+ for (RealmModel realm : realms) {
+ if (realm.getAuthenticationFlows().size() == 0) {
+ DefaultAuthenticationFlows.addFlows(realm);
+ }
+
+ migrateLDAPProviders(session, realm);
+ }
+
+ }
+
+ private void migrateLDAPProviders(KeycloakSession session, RealmModel realm) {
+ List<UserFederationProviderModel> federationProviders = realm.getUserFederationProviders();
+ for (UserFederationProviderModel fedProvider : federationProviders) {
+
+ if (fedProvider.getProviderName().equals(LDAPConstants.LDAP_PROVIDER)) {
+ Map<String, String> config = fedProvider.getConfig();
+
+ // Update config properties for LDAP federation provider
+ if (config.get(LDAPConstants.SEARCH_SCOPE) == null) {
+ config.put(LDAPConstants.SEARCH_SCOPE, String.valueOf(SearchControls.SUBTREE_SCOPE));
+ }
+
+ String usersDn = config.remove("userDnSuffix");
+ if (usersDn != null && config.get(LDAPConstants.USERS_DN) == null) {
+ config.put(LDAPConstants.USERS_DN, usersDn);
+ }
+
+ String usernameLdapAttribute = config.get(LDAPConstants.USERNAME_LDAP_ATTRIBUTE);
+ if (usernameLdapAttribute != null && config.get(LDAPConstants.RDN_LDAP_ATTRIBUTE) == null) {
+ if (usernameLdapAttribute.equalsIgnoreCase(LDAPConstants.SAM_ACCOUNT_NAME)) {
+ config.put(LDAPConstants.RDN_LDAP_ATTRIBUTE, LDAPConstants.CN);
+ } else {
+ config.put(LDAPConstants.RDN_LDAP_ATTRIBUTE, usernameLdapAttribute);
+ }
+ }
+
+ if (config.get(LDAPConstants.UUID_LDAP_ATTRIBUTE) == null) {
+ String uuidAttrName = LDAPConstants.getUuidAttributeName(config.get(LDAPConstants.VENDOR));
+ config.put(LDAPConstants.UUID_LDAP_ATTRIBUTE, uuidAttrName);
+ }
+
+ realm.updateUserFederationProvider(fedProvider);
+
+ // Create default mappers for LDAP
+ Set<UserFederationMapperModel> mappers = realm.getUserFederationMappersByFederationProvider(fedProvider.getId());
+ if (mappers.isEmpty()) {
+ UserFederationProviderFactory ldapFactory = (UserFederationProviderFactory) session.getKeycloakSessionFactory().getProviderFactory(UserFederationProvider.class, LDAPConstants.LDAP_PROVIDER);
+ if (ldapFactory != null) {
+ ((UserFederationEventAwareProviderFactory) ldapFactory).onProviderModelCreated(realm, fedProvider);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/model/api/src/main/java/org/keycloak/migration/ModelVersion.java b/model/api/src/main/java/org/keycloak/migration/ModelVersion.java
index 1dfcd14..095576a 100755
--- a/model/api/src/main/java/org/keycloak/migration/ModelVersion.java
+++ b/model/api/src/main/java/org/keycloak/migration/ModelVersion.java
@@ -59,7 +59,7 @@ public class ModelVersion {
if (major < version.major) return true;
if (minor < version.minor) return true;
if (micro < version.micro) return true;
- if (qualifier == version.qualifier) return false;
+ if (qualifier != null && qualifier.equals(version.qualifier)) return false;
if (qualifier == null) return false;
if (version.qualifier == null) return true;
int comp = qualifier.compareTo(version.qualifier);
diff --git a/model/api/src/main/java/org/keycloak/models/entities/UsernameLoginFailureEntity.java b/model/api/src/main/java/org/keycloak/models/entities/UsernameLoginFailureEntity.java
index e25e717..e6123f3 100644
--- a/model/api/src/main/java/org/keycloak/models/entities/UsernameLoginFailureEntity.java
+++ b/model/api/src/main/java/org/keycloak/models/entities/UsernameLoginFailureEntity.java
@@ -60,4 +60,11 @@ public class UsernameLoginFailureEntity extends AbstractIdentifiableEntity {
public void setRealmId(String realmId) {
this.realmId = realmId;
}
+
+ public void clearFailures() {
+ this.numFailures = 0;
+ this.lastFailure = 0;
+ this.lastIPFailure = null;
+ this.failedLoginNotBefore = 0;
+ }
}
diff --git a/model/api/src/main/java/org/keycloak/models/LDAPConstants.java b/model/api/src/main/java/org/keycloak/models/LDAPConstants.java
index 22f8979..0d97664 100644
--- a/model/api/src/main/java/org/keycloak/models/LDAPConstants.java
+++ b/model/api/src/main/java/org/keycloak/models/LDAPConstants.java
@@ -5,6 +5,8 @@ package org.keycloak.models;
*/
public class LDAPConstants {
+ public static final String LDAP_PROVIDER = "ldap";
+
public static final String VENDOR = "vendor";
public static final String VENDOR_RHDS = "rhds";
public static final String VENDOR_ACTIVE_DIRECTORY = "ad";
@@ -80,4 +82,21 @@ public class LDAPConstants {
public static final String OBJECT_GUID = "objectGUID";
public static final String CREATE_TIMESTAMP = "createTimestamp";
public static final String MODIFY_TIMESTAMP = "modifyTimestamp";
+
+ public static String getUuidAttributeName(String vendor) {
+ if (vendor != null) {
+ switch (vendor) {
+ case VENDOR_RHDS:
+ return "nsuniqueid";
+ case VENDOR_TIVOLI:
+ return "uniqueidentifier";
+ case VENDOR_NOVELL_EDIRECTORY:
+ return "guid";
+ case VENDOR_ACTIVE_DIRECTORY:
+ return OBJECT_GUID;
+ }
+ }
+
+ return ENTRY_UUID;
+ }
}
diff --git a/model/api/src/main/java/org/keycloak/models/UserFederationEventAwareProviderFactory.java b/model/api/src/main/java/org/keycloak/models/UserFederationEventAwareProviderFactory.java
index 866bf79..b409d87 100644
--- a/model/api/src/main/java/org/keycloak/models/UserFederationEventAwareProviderFactory.java
+++ b/model/api/src/main/java/org/keycloak/models/UserFederationEventAwareProviderFactory.java
@@ -29,5 +29,5 @@ public abstract class UserFederationEventAwareProviderFactory implements UserFed
});
}
- protected abstract void onProviderModelCreated(RealmModel realm, UserFederationProviderModel createdProviderModel);
+ public abstract void onProviderModelCreated(RealmModel realm, UserFederationProviderModel createdProviderModel);
}
diff --git a/model/api/src/main/java/org/keycloak/models/UserFederationManager.java b/model/api/src/main/java/org/keycloak/models/UserFederationManager.java
index 945b8d8..7d9e7ca 100755
--- a/model/api/src/main/java/org/keycloak/models/UserFederationManager.java
+++ b/model/api/src/main/java/org/keycloak/models/UserFederationManager.java
@@ -20,7 +20,7 @@ public class UserFederationManager implements UserProvider {
protected KeycloakSession session;
- // Set of already validated/proxied users during this session. Key is user ID
+ // Set of already validated/proxied federation users during this session. Key is user ID
private Map<String, UserModel> managedUsers = new HashMap<>();
public UserFederationManager(KeycloakSession session) {
diff --git a/model/api/src/main/java/org/keycloak/models/UserFederationProvider.java b/model/api/src/main/java/org/keycloak/models/UserFederationProvider.java
index 7c97d67..8fdd45a 100755
--- a/model/api/src/main/java/org/keycloak/models/UserFederationProvider.java
+++ b/model/api/src/main/java/org/keycloak/models/UserFederationProvider.java
@@ -44,11 +44,12 @@ public interface UserFederationProvider extends Provider {
/**
* Gives the provider an option to validate if user still exists in federation backend and then proxy UserModel loaded from local storage.
- * This method is called whenever a UserModel is pulled from local storage.
+ * This method is called whenever a UserModel is pulled from Keycloak local storage.
* For example, the LDAP provider proxies the UserModel and does on-demand synchronization with
* LDAP whenever UserModel update methods are invoked. It also overrides UserModel.updateCredential for the
* credential types it supports
*
+ * @param realm
* @param local
* @return null if user is no longer valid or proxy object otherwise
*/
@@ -122,6 +123,7 @@ public interface UserFederationProvider extends Provider {
* Is the Keycloak UserModel still valid and/or existing in federated storage? Keycloak may call this method
* in various user operations. The local storage may be deleted if this method returns false.
*
+ * @param realm
* @param local
* @return
*/
diff --git a/model/api/src/test/java/org/keycloak/models/MigrationVersionTest.java b/model/api/src/test/java/org/keycloak/models/MigrationVersionTest.java
index c706d8a..9bdd231 100755
--- a/model/api/src/test/java/org/keycloak/models/MigrationVersionTest.java
+++ b/model/api/src/test/java/org/keycloak/models/MigrationVersionTest.java
@@ -16,30 +16,30 @@ public class MigrationVersionTest {
Assert.assertEquals(version_100Beta1.getMajor(), 1);
Assert.assertEquals(version_100Beta1.getMinor(), 0);
Assert.assertEquals(version_100Beta1.getMicro(), 0);
- ModelVersion version_100RC1 = new ModelVersion("1.0.0.RC1");
+ ModelVersion version_100CR1 = new ModelVersion("1.0.0.CR1");
ModelVersion version_100 = new ModelVersion("1.0.0");
ModelVersion version_110Beta1 = new ModelVersion("1.1.0.Beta1");
- ModelVersion version_110RC1 = new ModelVersion("1.1.0.RC1");
+ ModelVersion version_110CR1 = new ModelVersion("1.1.0.CR1");
ModelVersion version_110 = new ModelVersion("1.1.0");
ModelVersion version_111Beta1 = new ModelVersion("1.1.1.Beta1");
- ModelVersion version_111RC1 = new ModelVersion("1.1.1.RC1");
+ ModelVersion version_111CR1 = new ModelVersion("1.1.1.CR1");
ModelVersion version_111 = new ModelVersion("1.1.1");
ModelVersion version_211Beta1 = new ModelVersion("2.1.1.Beta1");
- ModelVersion version_211RC1 = new ModelVersion("2.1.1.RC1");
- Assert.assertEquals(version_211RC1.getMajor(), 2);
- Assert.assertEquals(version_211RC1.getMinor(), 1);
- Assert.assertEquals(version_211RC1.getMicro(), 1);
- Assert.assertEquals(version_211RC1.getQualifier(), "RC1");
+ ModelVersion version_211CR1 = new ModelVersion("2.1.1.CR1");
+ Assert.assertEquals(version_211CR1.getMajor(), 2);
+ Assert.assertEquals(version_211CR1.getMinor(), 1);
+ Assert.assertEquals(version_211CR1.getMicro(), 1);
+ Assert.assertEquals(version_211CR1.getQualifier(), "CR1");
ModelVersion version_211 = new ModelVersion("2.1.1");
Assert.assertFalse(version_100Beta1.lessThan(version_100Beta1));
- Assert.assertTrue(version_100Beta1.lessThan(version_100RC1));
+ Assert.assertTrue(version_100Beta1.lessThan(version_100CR1));
Assert.assertTrue(version_100Beta1.lessThan(version_100));
Assert.assertTrue(version_100Beta1.lessThan(version_110Beta1));
- Assert.assertTrue(version_100Beta1.lessThan(version_110RC1));
+ Assert.assertTrue(version_100Beta1.lessThan(version_110CR1));
Assert.assertTrue(version_100Beta1.lessThan(version_110));
- Assert.assertFalse(version_211.lessThan(version_110RC1));
+ Assert.assertFalse(version_211.lessThan(version_110CR1));
}
}
model/file/pom.xml 2(+1 -1)
diff --git a/model/file/pom.xml b/model/file/pom.xml
index 564201f..0e5c11f 100755
--- a/model/file/pom.xml
+++ b/model/file/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/model/invalidation-cache/infinispan/pom.xml b/model/invalidation-cache/infinispan/pom.xml
index cb9ccea..2b9501b 100755
--- a/model/invalidation-cache/infinispan/pom.xml
+++ b/model/invalidation-cache/infinispan/pom.xml
@@ -4,13 +4,13 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-invalidation-cache-infinispan</artifactId>
- <name>Keycloak Invalidation Cache Infinispan</name>
+ <name>Keycloak Model Invalidation Cache Infinispan</name>
<description/>
<dependencies>
diff --git a/model/invalidation-cache/model-adapters/pom.xml b/model/invalidation-cache/model-adapters/pom.xml
index 1be7be4..ee61f1f 100755
--- a/model/invalidation-cache/model-adapters/pom.xml
+++ b/model/invalidation-cache/model-adapters/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheUserProvider.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheUserProvider.java
index 750eebe..994c5d1 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheUserProvider.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheUserProvider.java
@@ -31,9 +31,9 @@ public class DefaultCacheUserProvider implements CacheUserProvider {
protected boolean transactionActive;
protected boolean setRollbackOnly;
- protected Map<String, String> userInvalidations = new HashMap<String, String>();
- protected Set<String> realmInvalidations = new HashSet<String>();
- protected Map<String, UserModel> managedUsers = new HashMap<String, UserModel>();
+ protected Map<String, String> userInvalidations = new HashMap<>();
+ protected Set<String> realmInvalidations = new HashSet<>();
+ protected Map<String, UserModel> managedUsers = new HashMap<>();
protected boolean clearAll;
@@ -251,12 +251,16 @@ public class DefaultCacheUserProvider implements CacheUserProvider {
@Override
public UserModel addUser(RealmModel realm, String id, String username, boolean addDefaultRoles, boolean addDefaultRequiredActions) {
- return getDelegate().addUser(realm, id, username, addDefaultRoles, addDefaultRequiredActions);
+ UserModel user = getDelegate().addUser(realm, id, username, addDefaultRoles, addDefaultRoles);
+ managedUsers.put(user.getId(), user);
+ return user;
}
@Override
public UserModel addUser(RealmModel realm, String username) {
- return getDelegate().addUser(realm, username);
+ UserModel user = getDelegate().addUser(realm, username);
+ managedUsers.put(user.getId(), user);
+ return user;
}
@Override
model/invalidation-cache/pom.xml 4(+2 -2)
diff --git a/model/invalidation-cache/pom.xml b/model/invalidation-cache/pom.xml
index c79a2a3..e48a4d0 100755
--- a/model/invalidation-cache/pom.xml
+++ b/model/invalidation-cache/pom.xml
@@ -3,10 +3,10 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
- <name>Model Parent</name>
+ <name>Keycloak Model Invalidation Cache Parent</name>
<description/>
<modelVersion>4.0.0</modelVersion>
model/jpa/pom.xml 2(+1 -1)
diff --git a/model/jpa/pom.xml b/model/jpa/pom.xml
index 4e64488..d96c261 100755
--- a/model/jpa/pom.xml
+++ b/model/jpa/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/IdentityProviderEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/IdentityProviderEntity.java
index 4cfefb4..eeef707 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/IdentityProviderEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/IdentityProviderEntity.java
@@ -41,7 +41,7 @@ public class IdentityProviderEntity {
@Column(name="ENABLED")
private boolean enabled;
- @Column(name = "UPDATE_PROFILE_FIRST_LOGIN_MODE")
+ @Column(name = "UPDATE_PROFILE_FIRST_LGN_MD")
private String updateProfileFirstLoginMode;
@Column(name = "TRUST_EMAIL")
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
index 9978aba..33ea232 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
@@ -804,18 +804,23 @@ public class RealmAdapter implements RealmModel {
if (entity.getId().equals(provider.getId())) {
session.users().preRemove(this, provider);
+ removeFederationMappersForProvider(provider.getId());
- Set<UserFederationMapperEntity> mappers = getUserFederationMapperEntitiesByFederationProvider(provider.getId());
- for (UserFederationMapperEntity mapper : mappers) {
- realm.getUserFederationMappers().remove(mapper);
- em.remove(mapper);
- }
it.remove();
em.remove(entity);
return;
}
}
}
+
+ private void removeFederationMappersForProvider(String federationProviderId) {
+ Set<UserFederationMapperEntity> mappers = getUserFederationMapperEntitiesByFederationProvider(federationProviderId);
+ for (UserFederationMapperEntity mapper : mappers) {
+ realm.getUserFederationMappers().remove(mapper);
+ em.remove(mapper);
+ }
+ }
+
@Override
public void updateUserFederationProvider(UserFederationProviderModel model) {
KeycloakModelUtils.ensureUniqueDisplayName(model.getDisplayName(), model, getUserFederationProviders());
@@ -855,10 +860,9 @@ public class RealmAdapter implements RealmModel {
entity.setConfig(model.getConfig());
entity.setPriority(model.getPriority());
entity.setProviderName(model.getProviderName());
- entity.setPriority(model.getPriority());
String displayName = model.getDisplayName();
if (displayName != null) {
- entity.setDisplayName(model.getDisplayName());
+ entity.setDisplayName(displayName);
}
entity.setFullSyncPeriod(model.getFullSyncPeriod());
entity.setChangedSyncPeriod(model.getChangedSyncPeriod());
@@ -871,6 +875,8 @@ public class RealmAdapter implements RealmModel {
if (found) continue;
session.users().preRemove(this, new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName(),
entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity.getLastSync()));
+ removeFederationMappersForProvider(entity.getId());
+
it.remove();
em.remove(entity);
}
model/mongo/pom.xml 2(+1 -1)
diff --git a/model/mongo/pom.xml b/model/mongo/pom.xml
index a8f4376..df7f9d8 100755
--- a/model/mongo/pom.xml
+++ b/model/mongo/pom.xml
@@ -5,7 +5,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
index 4b8090c..45456de 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
@@ -877,11 +877,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
if (entity.getId().equals(provider.getId())) {
session.users().preRemove(this, new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName(),
entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity.getLastSync()));
-
- Set<UserFederationMapperEntity> mappers = getUserFederationMapperEntitiesByFederationProvider(provider.getId());
- for (UserFederationMapperEntity mapper : mappers) {
- getMongoEntity().getUserFederationMappers().remove(mapper);
- }
+ removeFederationMappersForProvider(provider.getId());
it.remove();
}
@@ -889,6 +885,13 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
updateRealm();
}
+ private void removeFederationMappersForProvider(String federationProviderId) {
+ Set<UserFederationMapperEntity> mappers = getUserFederationMapperEntitiesByFederationProvider(federationProviderId);
+ for (UserFederationMapperEntity mapper : mappers) {
+ getMongoEntity().getUserFederationMappers().remove(mapper);
+ }
+ }
+
@Override
public void updateUserFederationProvider(UserFederationProviderModel model) {
KeycloakModelUtils.ensureUniqueDisplayName(model.getDisplayName(), model, getUserFederationProviders());
@@ -943,8 +946,52 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
KeycloakModelUtils.ensureUniqueDisplayName(currentProvider.getDisplayName(), currentProvider, providers);
}
- List<UserFederationProviderEntity> entities = new LinkedList<UserFederationProviderEntity>();
+ List<UserFederationProviderEntity> existingProviders = realm.getUserFederationProviders();
+ List<UserFederationProviderEntity> toRemove = new LinkedList<>();
+ for (UserFederationProviderEntity entity : existingProviders) {
+ boolean found = false;
+ for (UserFederationProviderModel model : providers) {
+ if (entity.getId().equals(model.getId())) {
+ entity.setConfig(model.getConfig());
+ entity.setPriority(model.getPriority());
+ entity.setProviderName(model.getProviderName());
+ String displayName = model.getDisplayName();
+ if (displayName != null) {
+ entity.setDisplayName(displayName);
+ }
+ entity.setFullSyncPeriod(model.getFullSyncPeriod());
+ entity.setChangedSyncPeriod(model.getChangedSyncPeriod());
+ entity.setLastSync(model.getLastSync());
+ found = true;
+ break;
+ }
+
+ }
+ if (found) continue;
+ session.users().preRemove(this, new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName(),
+ entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity.getLastSync()));
+ removeFederationMappersForProvider(entity.getId());
+
+ toRemove.add(entity);
+ }
+
+ for (UserFederationProviderEntity entity : toRemove) {
+ realm.getUserFederationProviders().remove(entity);
+ }
+
+ List<UserFederationProviderModel> add = new LinkedList<UserFederationProviderModel>();
for (UserFederationProviderModel model : providers) {
+ boolean found = false;
+ for (UserFederationProviderEntity entity : realm.getUserFederationProviders()) {
+ if (entity.getId().equals(model.getId())) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) add.add(model);
+ }
+
+ for (UserFederationProviderModel model : add) {
UserFederationProviderEntity entity = new UserFederationProviderEntity();
if (model.getId() != null) {
entity.setId(model.getId());
@@ -964,12 +1011,11 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
entity.setFullSyncPeriod(model.getFullSyncPeriod());
entity.setChangedSyncPeriod(model.getChangedSyncPeriod());
entity.setLastSync(model.getLastSync());
- entities.add(entity);
+ realm.getUserFederationProviders().add(entity);
session.getKeycloakSessionFactory().publish(new UserFederationProviderCreationEventImpl(this, model));
}
- realm.setUserFederationProviders(entities);
updateRealm();
}
model/pom.xml 4(+2 -2)
diff --git a/model/pom.xml b/model/pom.xml
index 2e0bb73..1d2296d 100755
--- a/model/pom.xml
+++ b/model/pom.xml
@@ -3,10 +3,10 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
- <name>Model Parent</name>
+ <name>Keycloak Model Parent</name>
<description/>
<modelVersion>4.0.0</modelVersion>
model/sessions-infinispan/pom.xml 2(+1 -1)
diff --git a/model/sessions-infinispan/pom.xml b/model/sessions-infinispan/pom.xml
index 56b15c5..0093184 100755
--- a/model/sessions-infinispan/pom.xml
+++ b/model/sessions-infinispan/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/model/sessions-infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/LoginFailureEntity.java b/model/sessions-infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/LoginFailureEntity.java
index 8bb05e7..b330c2e 100644
--- a/model/sessions-infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/LoginFailureEntity.java
+++ b/model/sessions-infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/LoginFailureEntity.java
@@ -62,4 +62,10 @@ public class LoginFailureEntity implements Serializable {
this.lastIPFailure = lastIPFailure;
}
+ public void clearFailures() {
+ this.failedLoginNotBefore = 0;
+ this.numFailures = 0;
+ this.lastFailure = 0;
+ this.lastIPFailure = null;
+ }
}
diff --git a/model/sessions-infinispan/src/main/java/org/keycloak/models/sessions/infinispan/UsernameLoginFailureAdapter.java b/model/sessions-infinispan/src/main/java/org/keycloak/models/sessions/infinispan/UsernameLoginFailureAdapter.java
index fed8f28..c478a0f 100755
--- a/model/sessions-infinispan/src/main/java/org/keycloak/models/sessions/infinispan/UsernameLoginFailureAdapter.java
+++ b/model/sessions-infinispan/src/main/java/org/keycloak/models/sessions/infinispan/UsernameLoginFailureAdapter.java
@@ -51,7 +51,7 @@ public class UsernameLoginFailureAdapter implements UsernameLoginFailureModel {
@Override
public void clearFailures() {
- entity.setNumFailures(0);
+ entity.clearFailures();
update();
}
model/sessions-jpa/pom.xml 2(+1 -1)
diff --git a/model/sessions-jpa/pom.xml b/model/sessions-jpa/pom.xml
index f8f5289..2225012 100755
--- a/model/sessions-jpa/pom.xml
+++ b/model/sessions-jpa/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/entities/UsernameLoginFailureEntity.java b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/entities/UsernameLoginFailureEntity.java
index c62e474..d03f597 100755
--- a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/entities/UsernameLoginFailureEntity.java
+++ b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/entities/UsernameLoginFailureEntity.java
@@ -91,6 +91,13 @@ public class UsernameLoginFailureEntity {
this.realmId = realmId;
}
+ public void clearFailures() {
+ setFailedLoginNotBefore(0);
+ setLastFailure(0);
+ setLastIPFailure(null);
+ setNumFailures(0);
+ }
+
public static class Key implements Serializable {
private String realmId;
diff --git a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/UsernameLoginFailureAdapter.java b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/UsernameLoginFailureAdapter.java
index b5852bb..9293648 100755
--- a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/UsernameLoginFailureAdapter.java
+++ b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/UsernameLoginFailureAdapter.java
@@ -43,7 +43,7 @@ public class UsernameLoginFailureAdapter implements UsernameLoginFailureModel
@Override
public void clearFailures() {
- user.setNumFailures(0);
+ user.clearFailures();
}
@Override
model/sessions-mem/pom.xml 2(+1 -1)
diff --git a/model/sessions-mem/pom.xml b/model/sessions-mem/pom.xml
index 86b9559..f630a80 100755
--- a/model/sessions-mem/pom.xml
+++ b/model/sessions-mem/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/entities/UsernameLoginFailureEntity.java b/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/entities/UsernameLoginFailureEntity.java
index b1788d2..32cf981 100644
--- a/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/entities/UsernameLoginFailureEntity.java
+++ b/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/entities/UsernameLoginFailureEntity.java
@@ -62,4 +62,11 @@ public class UsernameLoginFailureEntity {
this.lastIpFailure = lastIpFailure;
}
+ public void clearFailures() {
+ this.failedLoginNotBefore = new AtomicInteger();
+ this.lastFailure = new AtomicLong();
+ this.lastIpFailure = new AtomicReference<String>();
+ this.numFailures = new AtomicInteger();
+ }
+
}
diff --git a/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/UsernameLoginFailureAdapter.java b/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/UsernameLoginFailureAdapter.java
index 03dc558..e47a643 100644
--- a/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/UsernameLoginFailureAdapter.java
+++ b/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/UsernameLoginFailureAdapter.java
@@ -45,7 +45,7 @@ public class UsernameLoginFailureAdapter implements UsernameLoginFailureModel {
@Override
public void clearFailures() {
- entity.getNumFailures().set(0);
+ entity.clearFailures();
}
@Override
model/sessions-mongo/pom.xml 2(+1 -1)
diff --git a/model/sessions-mongo/pom.xml b/model/sessions-mongo/pom.xml
index b856155..3774a6f 100755
--- a/model/sessions-mongo/pom.xml
+++ b/model/sessions-mongo/pom.xml
@@ -5,7 +5,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/UsernameLoginFailureAdapter.java b/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/UsernameLoginFailureAdapter.java
index 7d28125..251d26e 100755
--- a/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/UsernameLoginFailureAdapter.java
+++ b/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/UsernameLoginFailureAdapter.java
@@ -50,7 +50,7 @@ public class UsernameLoginFailureAdapter extends AbstractMongoAdapter<MongoUser
@Override
public void clearFailures() {
- user.setNumFailures(0);
+ user.clearFailures();
updateMongoEntity();
}
pom.xml 57(+28 -29)
diff --git a/pom.xml b/pom.xml
index 68471dc..0bb8beb 100755
--- a/pom.xml
+++ b/pom.xml
@@ -14,7 +14,7 @@
</description>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-parent</artifactId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
@@ -26,8 +26,8 @@
<jackson.version>1.9.9</jackson.version>
<apache.httpcomponents.version>4.3.6</apache.httpcomponents.version>
<apache.httpcomponents.httpcore.version>4.3.3</apache.httpcomponents.httpcore.version>
- <resteasy.version>3.0.10.Final</resteasy.version>
- <resteasy.version.latest>3.0.10.Final</resteasy.version.latest>
+ <resteasy.version>2.3.7.Final</resteasy.version>
+ <resteasy.latest.version>3.0.9.Final</resteasy.latest.version>
<joda-time.version>2.7</joda-time.version>
<keycloak.apache.httpcomponents.version>4.2.1</keycloak.apache.httpcomponents.version>
<!-- <undertow.version>1.1.0.Final</undertow.version> -->
@@ -42,14 +42,14 @@
<xnio.netty.netty-xnio-transport.version>0.1.1.Final</xnio.netty.netty-xnio-transport.version>
<hibernate.javax.persistence.version>1.0.1.Final</hibernate.javax.persistence.version>
<hibernate.entitymanager.version>4.0.1.Final</hibernate.entitymanager.version>
- <h2.version>1.3.168</h2.version>
+ <h2.version>1.4.187</h2.version>
<mysql.version>5.1.29</mysql.version>
<postgresql.version>9.3-1100-jdbc41</postgresql.version>
<dom4j.version>1.6.1</dom4j.version>
<xml-apis.version>1.4.01</xml-apis.version>
<slf4j.version>1.7.7.jbossorg-1</slf4j.version>
- <wildfly.version>9.0.0.CR1</wildfly.version>
- <wildfly.core.version>1.0.0.CR1</wildfly.core.version>
+ <wildfly.version>9.0.0.CR2</wildfly.version>
+ <wildfly.core.version>1.0.0.CR6</wildfly.core.version>
<wildfly.build-tools.version>1.0.0.Alpha8</wildfly.build-tools.version>
<!-- this is EAP 6.4 alpha, publicly available -->
@@ -70,7 +70,7 @@
<sun.xsom.version>20140925</sun.xsom.version>
<javax.mail.version>1.4.5</javax.mail.version>
<infinispan.version>6.0.2.Final</infinispan.version>
- <liquibase.version>3.3.2</liquibase.version>
+ <liquibase.version>3.3.5</liquibase.version>
<jetty9.version>9.1.0.v20131115</jetty9.version>
<osgi.version>4.2.0</osgi.version>
<pax.web.version>3.1.2</pax.web.version>
@@ -255,18 +255,12 @@
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
- <version>${resteasy.version}</version>
+ <version>${resteasy.latest.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-undertow</artifactId>
- <version>${resteasy.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.jboss.resteasy</groupId>
- <artifactId>async-http-servlet-3.0</artifactId>
- <version>${resteasy.version}</version>
+ <version>${resteasy.latest.version}</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -290,11 +284,6 @@
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>org.keycloak</groupId>
- <artifactId>keycloak-undertow-adapter</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
<groupId>io.undertow</groupId>
<artifactId>undertow-servlet</artifactId>
<version>${undertow.version}</version>
@@ -534,18 +523,13 @@
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
- <artifactId>httpmime</artifactId>
- <version>${apache.httpcomponents.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>${apache.httpcomponents.httpcore.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
- <version>${keycloak.apache.httpcomponents.version}</version>
+ <version>${apache.httpcomponents.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
@@ -884,6 +868,11 @@
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
+ <artifactId>keycloak-as7-server-subsystem</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.keycloak</groupId>
<artifactId>keycloak-wf8-subsystem</artifactId>
<version>${project.version}</version>
</dependency>
@@ -894,6 +883,10 @@
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
+ <artifactId>keycloak-wf9-server-subsystem</artifactId>
+ <version>${project.version}</version>
+ </dependency> <dependency>
+ <groupId>org.keycloak</groupId>
<artifactId>keycloak-subsystem</artifactId>
<version>${project.version}</version>
</dependency>
@@ -1084,7 +1077,7 @@
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
- <artifactId>keycloak-jboss-modules</artifactId>
+ <artifactId>keycloak-eap6-server-modules</artifactId>
<version>${project.version}</version>
<type>zip</type>
</dependency>
@@ -1108,7 +1101,13 @@
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
- <artifactId>keycloak-server-overlay</artifactId>
+ <artifactId>keycloak-wf9-adapter-dist</artifactId>
+ <version>${project.version}</version>
+ <type>zip</type>
+ </dependency>
+ <dependency>
+ <groupId>org.keycloak</groupId>
+ <artifactId>keycloak-wf9-server-overlay</artifactId>
<version>${project.version}</version>
<type>zip</type>
</dependency>
@@ -1138,7 +1137,7 @@
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
- <artifactId>keycloak-wildfly-adapter-dist</artifactId>
+ <artifactId>keycloak-wf8-adapter-dist</artifactId>
<version>${project.version}</version>
<type>zip</type>
</dependency>
proxy/launcher/pom.xml 2(+1 -1)
diff --git a/proxy/launcher/pom.xml b/proxy/launcher/pom.xml
index 5108980..b1ed5aa 100755
--- a/proxy/launcher/pom.xml
+++ b/proxy/launcher/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
proxy/pom.xml 2(+1 -1)
diff --git a/proxy/pom.xml b/proxy/pom.xml
index 3ca449f..f8d5e7d 100755
--- a/proxy/pom.xml
+++ b/proxy/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<name>Model Parent</name>
proxy/proxy-server/pom.xml 2(+1 -1)
diff --git a/proxy/proxy-server/pom.xml b/proxy/proxy-server/pom.xml
index 0ea7a76..efd01b0 100755
--- a/proxy/proxy-server/pom.xml
+++ b/proxy/proxy-server/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
saml/pom.xml 2(+1 -1)
diff --git a/saml/pom.xml b/saml/pom.xml
index 2fb6a88..03f03b9 100755
--- a/saml/pom.xml
+++ b/saml/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<name>Keycloak SAML Integration</name>
saml/saml-core/pom.xml 2(+1 -1)
diff --git a/saml/saml-core/pom.xml b/saml/saml-core/pom.xml
index 0254ab6..cbda574 100755
--- a/saml/saml-core/pom.xml
+++ b/saml/saml-core/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
saml/saml-protocol/pom.xml 2(+1 -1)
diff --git a/saml/saml-protocol/pom.xml b/saml/saml-protocol/pom.xml
index d7b3ebb..32028fb 100755
--- a/saml/saml-protocol/pom.xml
+++ b/saml/saml-protocol/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlService.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlService.java
index 907bfb3..a557b5a 100755
--- a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlService.java
+++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlService.java
@@ -420,11 +420,21 @@ public class SamlService {
for (String sessionIndex : logoutRequest.getSessionIndex()) {
ClientSessionModel clientSession = session.sessions().getClientSession(realm, sessionIndex);
if (clientSession == null) continue;
+ UserSessionModel userSession = clientSession.getUserSession();
if (clientSession.getClient().getClientId().equals(client.getClientId())) {
// remove requesting client from logout
clientSession.setAction(ClientSessionModel.Action.LOGGED_OUT.name());
+
+ // Remove also other clientSessions of this client as there could be more in this UserSession
+ if (userSession != null) {
+ for (ClientSessionModel clientSession2 : userSession.getClientSessions()) {
+ if (clientSession2.getClient().getId().equals(client.getId())) {
+ clientSession2.setAction(ClientSessionModel.Action.LOGGED_OUT.name());
+ }
+ }
+ }
}
- UserSessionModel userSession = clientSession.getUserSession();
+
try {
authManager.backchannelLogout(session, realm, userSession, uriInfo, clientConnection, headers, true);
} catch (Exception e) {
services/pom.xml 2(+1 -1)
diff --git a/services/pom.xml b/services/pom.xml
index e39e846..b3017a0 100755
--- a/services/pom.xml
+++ b/services/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/services/src/main/java/org/keycloak/offlineconfig/AdminRecovery.java b/services/src/main/java/org/keycloak/offlineconfig/AdminRecovery.java
new file mode 100644
index 0000000..cb775b1
--- /dev/null
+++ b/services/src/main/java/org/keycloak/offlineconfig/AdminRecovery.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2015 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.keycloak.offlineconfig;
+
+import org.jboss.logging.Logger;
+import org.keycloak.Config;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionFactory;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RealmProvider;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.UserProvider;
+import org.keycloak.services.managers.ApplianceBootstrap;
+
+/**
+ * Static utility class that performs recovery on the master admin account.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2015 Red Hat Inc.
+ */
+public class AdminRecovery {
+ private static final Logger log = Logger.getLogger(AdminRecovery.class);
+
+ public static final String RECOVER_ADMIN_ACCOUNT = "keycloak.recover-admin";
+ public static final String TEMP_ADMIN_PASSWORD = "keycloak.temp-admin-password";
+
+ // Don't allow instances
+ private AdminRecovery() {}
+
+ public static void recover(KeycloakSessionFactory sessionFactory) {
+ if (!needRecovery()) return;
+
+ KeycloakSession session = sessionFactory.create();
+
+ session.getTransaction().begin();
+ try {
+ doRecover(session, getTempAdminPassword());
+ session.getTransaction().commit();
+ log.info("*******************************");
+ log.info("Recovered Master Admin account.");
+ log.info("*******************************");
+ } finally {
+ session.close();
+ System.clearProperty(RECOVER_ADMIN_ACCOUNT);
+ System.clearProperty(TEMP_ADMIN_PASSWORD);
+ }
+ }
+
+ private static boolean needRecovery() {
+ String strNeedRecovery = System.getProperty(RECOVER_ADMIN_ACCOUNT, "false");
+ return Boolean.parseBoolean(strNeedRecovery);
+ }
+
+ private static String getTempAdminPassword() {
+ String tempAdminPassword = System.getProperty(TEMP_ADMIN_PASSWORD);
+ if ((tempAdminPassword == null) || tempAdminPassword.isEmpty()) {
+ throw new OfflineConfigException("Must provide temporary admin password to recover admin account.");
+ }
+ return tempAdminPassword;
+ }
+
+ private static void doRecover(KeycloakSession session, String tempAdminPassword) {
+ RealmProvider realmProvider = session.realms();
+ UserProvider userProvider = session.users();
+
+ String adminRealmName = Config.getAdminRealm();
+ RealmModel realm = realmProvider.getRealmByName(adminRealmName);
+ UserModel adminUser = userProvider.getUserByUsername("admin", realm);
+
+ if (adminUser == null) {
+ adminUser = userProvider.addUser(realm, "admin");
+ }
+
+ ApplianceBootstrap.setupAdminUser(session, realm, adminUser, tempAdminPassword);
+ }
+}
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java
index 7582dcd..bdcbf73 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java
@@ -151,7 +151,7 @@ public class TokenEndpoint {
if (legacyGrantType != null) {
grantType = legacyGrantType;
} else {
- throw new ErrorResponseException("invalid_request", "Missing query parameter: " + OIDCLoginProtocol.GRANT_TYPE_PARAM, Response.Status.BAD_REQUEST);
+ throw new ErrorResponseException("invalid_request", "Missing form parameter: " + OIDCLoginProtocol.GRANT_TYPE_PARAM, Response.Status.BAD_REQUEST);
}
}
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/utils/AuthorizeClientUtil.java b/services/src/main/java/org/keycloak/protocol/oidc/utils/AuthorizeClientUtil.java
index a8a9e2a..0626f1c 100644
--- a/services/src/main/java/org/keycloak/protocol/oidc/utils/AuthorizeClientUtil.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/utils/AuthorizeClientUtil.java
@@ -39,7 +39,7 @@ public class AuthorizeClientUtil {
if (client_id == null) {
Map<String, String> error = new HashMap<String, String>();
error.put(OAuth2Constants.ERROR, "invalid_client");
- error.put(OAuth2Constants.ERROR_DESCRIPTION, "Could not find client");
+ error.put(OAuth2Constants.ERROR_DESCRIPTION, "Missing client_id parameter");
throw new BadRequestException("Could not find client", Response.status(Response.Status.BAD_REQUEST).entity(error).type(MediaType.APPLICATION_JSON_TYPE).build());
}
diff --git a/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java b/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
index 8760ff0..7510572 100755
--- a/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
+++ b/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
@@ -61,11 +61,15 @@ public class ApplianceBootstrap {
KeycloakModelUtils.generateRealmKeys(realm);
UserModel adminUser = session.users().addUser(realm, "admin");
+ setupAdminUser(session, realm, adminUser, "admin");
+ }
+
+ public static void setupAdminUser(KeycloakSession session, RealmModel realm, UserModel adminUser, String password) {
adminUser.setEnabled(true);
- UserCredentialModel password = new UserCredentialModel();
- password.setType(UserCredentialModel.PASSWORD);
- password.setValue("admin");
- session.users().updateCredential(realm, adminUser, password);
+ UserCredentialModel usrCredModel = new UserCredentialModel();
+ usrCredModel.setType(UserCredentialModel.PASSWORD);
+ usrCredModel.setValue(password);
+ session.users().updateCredential(realm, adminUser, usrCredModel);
adminUser.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
RoleModel adminRole = realm.getRole(AdminRoles.ADMIN);
diff --git a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
index 8d19950..a4b0276 100755
--- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
@@ -516,7 +516,6 @@ public class AuthenticationManager {
}
if (client.isConsentRequired()) {
- accessCode.setAction(ClientSessionModel.Action.OAUTH_GRANT.name());
UserConsentModel grantedConsent = user.getConsentByClient(client.getId());
@@ -547,11 +546,18 @@ public class AuthenticationManager {
// Skip grant screen if everything was already approved by this user
if (realmRoles.size() > 0 || resourceRoles.size() > 0 || protocolMappers.size() > 0) {
+ accessCode.setAction(ClientSessionModel.Action.OAUTH_GRANT.name());
+
return session.getProvider(LoginFormsProvider.class)
.setClientSessionCode(accessCode.getCode())
.setAccessRequest(realmRoles, resourceRoles, protocolMappers)
.createOAuthGrant(clientSession);
+ } else {
+ String consentDetail = (grantedConsent != null) ? Details.CONSENT_VALUE_PERSISTED_CONSENT : Details.CONSENT_VALUE_NO_CONSENT_REQUIRED;
+ event.detail(Details.CONSENT, consentDetail);
}
+ } else {
+ event.detail(Details.CONSENT, Details.CONSENT_VALUE_NO_CONSENT_REQUIRED);
}
return null;
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
index f72da8c..2a0a115 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
@@ -2,6 +2,7 @@ package org.keycloak.services.resources.admin;
import org.jboss.logging.Logger;
import org.jboss.resteasy.annotations.cache.NoCache;
+import org.jboss.resteasy.spi.BadRequestException;
import org.jboss.resteasy.spi.NotFoundException;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.keycloak.ClientConnection;
@@ -38,7 +39,6 @@ import org.keycloak.services.managers.UsersSyncManager;
import org.keycloak.services.ErrorResponse;
import org.keycloak.timer.TimerProvider;
-import javax.ws.rs.BadRequestException;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
@@ -196,8 +196,9 @@ public class RealmAdminResource {
} catch (PatternSyntaxException e) {
return ErrorResponse.error("Specified regex pattern(s) is invalid.", Response.Status.BAD_REQUEST);
} catch (ModelDuplicateException e) {
- return ErrorResponse.exists("Realm " + rep.getRealm() + " already exists.");
- } catch (Exception e) {
+ throw e;
+ } catch (Exception e) {
+ logger.error(e);
return ErrorResponse.error("Failed to update " + rep.getRealm() + " Realm.", Response.Status.INTERNAL_SERVER_ERROR);
}
}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
index a5c8d3d..b27e453 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
@@ -71,6 +71,8 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
+import org.keycloak.models.UsernameLoginFailureModel;
+import org.keycloak.services.managers.BruteForceProtector;
/**
* Base resource for managing users
@@ -84,9 +86,9 @@ public class UsersResource {
protected RealmModel realm;
private RealmAuth auth;
-
+
private AdminEventBuilder adminEvent;
-
+
@Context
protected ClientConnection clientConnection;
@@ -99,6 +101,9 @@ public class UsersResource {
@Context
protected HttpHeaders headers;
+ @Context
+ protected BruteForceProtector protector;
+
public UsersResource(RealmModel realm, RealmAuth auth, TokenManager tokenManager, AdminEventBuilder adminEvent) {
this.auth = auth;
this.realm = realm;
@@ -134,6 +139,13 @@ public class UsersResource {
attrsToRemove = Collections.emptySet();
}
+ if (rep.isEnabled()) {
+ UsernameLoginFailureModel failureModel = session.sessions().getUserLoginFailure(realm, rep.getUsername());
+ if (failureModel != null) {
+ failureModel.clearFailures();
+ }
+ }
+
updateUserFromRep(user, rep, attrsToRemove);
adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).representation(rep).success();
@@ -172,13 +184,13 @@ public class UsersResource {
UserModel user = session.users().addUser(realm, rep.getUsername());
Set<String> emptySet = Collections.emptySet();
updateUserFromRep(user, rep, emptySet);
-
+
adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, user.getId()).representation(rep).success();
-
+
if (session.getTransaction().isActive()) {
session.getTransaction().commit();
}
-
+
return Response.created(uriInfo.getAbsolutePathBuilder().path(user.getId()).build()).build();
} catch (ModelDuplicateException e) {
if (session.getTransaction().isActive()) {
@@ -244,7 +256,7 @@ public class UsersResource {
if (user == null) {
throw new NotFoundException("User not found");
}
-
+
UserRepresentation rep = ModelToRepresentation.toRepresentation(user);
if (realm.isIdentityFederationEnabled()) {
@@ -258,6 +270,10 @@ public class UsersResource {
}
}
+ if ((protector != null) && protector.isTemporarilyDisabled(session, realm, rep.getUsername())) {
+ rep.setEnabled(false);
+ }
+
return rep;
}
@@ -696,7 +712,7 @@ public class UsersResource {
adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo, role.getId()).representation(roles).success();
}
}
-
+
}
@Path("{id}/role-mappings/clients/{client}")
@@ -710,7 +726,7 @@ public class UsersResource {
if (client == null) {
throw new NotFoundException("Client not found");
}
-
+
return new UserClientRoleMappingsResource(uriInfo, realm, auth, user, clientModel, adminEvent);
}
@@ -744,7 +760,7 @@ public class UsersResource {
throw new BadRequestException("Can't reset password as account is read only");
}
if (pass.isTemporary()) user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
-
+
adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success();
}
diff --git a/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java b/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java
index 5b27759..d45e706 100755
--- a/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java
+++ b/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java
@@ -315,6 +315,16 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
this.uriInfo, event);
}
+ @Override
+ public Response cancelled(String code) {
+ return session.getProvider(LoginFormsProvider.class).setClientSessionCode(code).createLogin();
+ }
+
+ @Override
+ public Response error(String code, String message) {
+ return session.getProvider(LoginFormsProvider.class).setClientSessionCode(code).setError(message).createLogin();
+ }
+
private Response performAccountLinking(ClientSessionModel clientSession, BrokeredIdentityContext context, FederatedIdentityModel federatedIdentityModel, UserModel federatedUser) {
this.event.event(EventType.IDENTITY_PROVIDER_ACCCOUNT_LINKING);
diff --git a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
index e4c821c..0e32fe8 100755
--- a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
+++ b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
@@ -42,6 +42,7 @@ import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
+import org.keycloak.offlineconfig.AdminRecovery;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@@ -88,6 +89,7 @@ public class KeycloakApplication extends Application {
importRealms(context);
migrateModel();
+ AdminRecovery.recover(sessionFactory);
setupScheduledTasks(sessionFactory);
}
diff --git a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
index fc5278e..fae9564 100755
--- a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
+++ b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
@@ -326,7 +326,7 @@ public class LoginActionsService {
session.getContext().setClient(client);
if (!client.isEnabled()) {
- event.error(Errors.CLIENT_NOT_FOUND);
+ event.error(Errors.CLIENT_DISABLED);
return ErrorPage.error(session, Messages.LOGIN_REQUESTER_NOT_ENABLED);
}
@@ -418,7 +418,7 @@ public class LoginActionsService {
return ErrorPage.error(session, Messages.UNKNOWN_LOGIN_REQUESTER);
}
if (!client.isEnabled()) {
- event.error(Errors.CLIENT_NOT_FOUND);
+ event.error(Errors.CLIENT_DISABLED);
return ErrorPage.error(session, Messages.LOGIN_REQUESTER_NOT_ENABLED);
}
@@ -742,6 +742,7 @@ public class LoginActionsService {
}
user.updateConsent(grantedConsent);
+ event.detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED);
event.success();
return authManager.redirectAfterSuccessfulFlow(session, realm, userSession, clientSession, request, uriInfo, clientConnection);
social/core/pom.xml 2(+1 -1)
diff --git a/social/core/pom.xml b/social/core/pom.xml
index 5b67273..0cfc94a 100755
--- a/social/core/pom.xml
+++ b/social/core/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-social-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
social/facebook/pom.xml 2(+1 -1)
diff --git a/social/facebook/pom.xml b/social/facebook/pom.xml
index 7c9c02f..68c7357 100755
--- a/social/facebook/pom.xml
+++ b/social/facebook/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-social-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookIdentityProvider.java b/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookIdentityProvider.java
index ffce087..2c06212 100755
--- a/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookIdentityProvider.java
+++ b/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookIdentityProvider.java
@@ -3,10 +3,11 @@ package org.keycloak.social.facebook;
import org.codehaus.jackson.JsonNode;
import org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider;
import org.keycloak.broker.oidc.OAuth2IdentityProviderConfig;
+import org.keycloak.broker.oidc.mappers.AbstractJsonUserAttributeMapper;
import org.keycloak.broker.oidc.util.JsonSimpleHttp;
-import org.keycloak.broker.provider.util.SimpleHttp;
import org.keycloak.broker.provider.BrokeredIdentityContext;
import org.keycloak.broker.provider.IdentityBrokerException;
+import org.keycloak.broker.provider.util.SimpleHttp;
import org.keycloak.social.SocialIdentityProvider;
/**
@@ -14,63 +15,65 @@ import org.keycloak.social.SocialIdentityProvider;
*/
public class FacebookIdentityProvider extends AbstractOAuth2IdentityProvider implements SocialIdentityProvider {
- public static final String AUTH_URL = "https://graph.facebook.com/oauth/authorize";
- public static final String TOKEN_URL = "https://graph.facebook.com/oauth/access_token";
- public static final String PROFILE_URL = "https://graph.facebook.com/me";
- public static final String DEFAULT_SCOPE = "email";
+ public static final String AUTH_URL = "https://graph.facebook.com/oauth/authorize";
+ public static final String TOKEN_URL = "https://graph.facebook.com/oauth/access_token";
+ public static final String PROFILE_URL = "https://graph.facebook.com/me";
+ public static final String DEFAULT_SCOPE = "email";
+
+ public FacebookIdentityProvider(OAuth2IdentityProviderConfig config) {
+ super(config);
+ config.setAuthorizationUrl(AUTH_URL);
+ config.setTokenUrl(TOKEN_URL);
+ config.setUserInfoUrl(PROFILE_URL);
+ }
- public FacebookIdentityProvider(OAuth2IdentityProviderConfig config) {
- super(config);
- config.setAuthorizationUrl(AUTH_URL);
- config.setTokenUrl(TOKEN_URL);
- config.setUserInfoUrl(PROFILE_URL);
- }
+ protected BrokeredIdentityContext doGetFederatedIdentity(String accessToken) {
+ try {
+ JsonNode profile = JsonSimpleHttp.asJson(SimpleHttp.doGet(PROFILE_URL).header("Authorization", "Bearer " + accessToken));
- protected BrokeredIdentityContext doGetFederatedIdentity(String accessToken) {
- try {
- JsonNode profile = JsonSimpleHttp.asJson(SimpleHttp.doGet(PROFILE_URL).header("Authorization", "Bearer " + accessToken));
+ String id = getJsonProperty(profile, "id");
- String id = getJsonProperty(profile, "id");
+ BrokeredIdentityContext user = new BrokeredIdentityContext(id);
- BrokeredIdentityContext user = new BrokeredIdentityContext(id);
+ String email = getJsonProperty(profile, "email");
- String email = getJsonProperty(profile, "email");
+ user.setEmail(email);
- user.setEmail(email);
+ String username = getJsonProperty(profile, "username");
- String username = getJsonProperty(profile, "username");
+ if (username == null) {
+ if (email != null) {
+ username = email;
+ } else {
+ username = id;
+ }
+ }
- if (username == null) {
- if (email != null) {
- username = email;
- } else {
- username = id;
- }
- }
+ user.setUsername(username);
- user.setUsername(username);
+ String firstName = getJsonProperty(profile, "first_name");
+ String lastName = getJsonProperty(profile, "last_name");
- String firstName = getJsonProperty(profile, "first_name");
- String lastName = getJsonProperty(profile, "last_name");
+ if (lastName == null) {
+ lastName = "";
+ } else {
+ lastName = " " + lastName;
+ }
- if (lastName == null) {
- lastName = "";
- } else {
- lastName = " " + lastName;
- }
+ user.setName(firstName + lastName);
+ user.setIdpConfig(getConfig());
+ user.setIdp(this);
- user.setName(firstName + lastName);
- user.setIdpConfig(getConfig());
- user.setIdp(this);
+ AbstractJsonUserAttributeMapper.storeUserProfileForMapper(user, profile, getConfig().getAlias());
- return user;
- } catch (Exception e) {
- throw new IdentityBrokerException("Could not obtain user profile from facebook.", e);
- }
- }
+ return user;
+ } catch (Exception e) {
+ throw new IdentityBrokerException("Could not obtain user profile from facebook.", e);
+ }
+ }
- @Override
- protected String getDefaultScopes() {
- return DEFAULT_SCOPE;
- }
+ @Override
+ protected String getDefaultScopes() {
+ return DEFAULT_SCOPE;
+ }
}
diff --git a/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookUserAttributeMapper.java b/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookUserAttributeMapper.java
new file mode 100644
index 0000000..5a49657
--- /dev/null
+++ b/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookUserAttributeMapper.java
@@ -0,0 +1,29 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2015 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @authors tag. All rights reserved.
+ */
+package org.keycloak.social.facebook;
+
+import org.keycloak.broker.oidc.mappers.AbstractJsonUserAttributeMapper;
+
+/**
+ * User attribute mapper.
+ *
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class FacebookUserAttributeMapper extends AbstractJsonUserAttributeMapper {
+
+ private static final String[] cp = new String[] { FacebookIdentityProviderFactory.PROVIDER_ID };
+
+ @Override
+ public String[] getCompatibleProviders() {
+ return cp;
+ }
+
+ @Override
+ public String getId() {
+ return "facebook-user-attribute-mapper";
+ }
+
+}
diff --git a/social/facebook/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper b/social/facebook/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper
new file mode 100755
index 0000000..7e8f8aa
--- /dev/null
+++ b/social/facebook/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper
@@ -0,0 +1 @@
+org.keycloak.social.facebook.FacebookUserAttributeMapper
\ No newline at end of file
social/github/pom.xml 2(+1 -1)
diff --git a/social/github/pom.xml b/social/github/pom.xml
index 3bd1354..c969296 100755
--- a/social/github/pom.xml
+++ b/social/github/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-social-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/social/github/src/main/java/org/keycloak/social/github/GitHubIdentityProvider.java b/social/github/src/main/java/org/keycloak/social/github/GitHubIdentityProvider.java
index 40a883b..b89d3b9 100755
--- a/social/github/src/main/java/org/keycloak/social/github/GitHubIdentityProvider.java
+++ b/social/github/src/main/java/org/keycloak/social/github/GitHubIdentityProvider.java
@@ -3,10 +3,11 @@ package org.keycloak.social.github;
import org.codehaus.jackson.JsonNode;
import org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider;
import org.keycloak.broker.oidc.OAuth2IdentityProviderConfig;
+import org.keycloak.broker.oidc.mappers.AbstractJsonUserAttributeMapper;
import org.keycloak.broker.oidc.util.JsonSimpleHttp;
-import org.keycloak.broker.provider.util.SimpleHttp;
import org.keycloak.broker.provider.BrokeredIdentityContext;
import org.keycloak.broker.provider.IdentityBrokerException;
+import org.keycloak.broker.provider.util.SimpleHttp;
import org.keycloak.social.SocialIdentityProvider;
/**
@@ -14,40 +15,42 @@ import org.keycloak.social.SocialIdentityProvider;
*/
public class GitHubIdentityProvider extends AbstractOAuth2IdentityProvider implements SocialIdentityProvider {
- public static final String AUTH_URL = "https://github.com/login/oauth/authorize";
- public static final String TOKEN_URL = "https://github.com/login/oauth/access_token";
- public static final String PROFILE_URL = "https://api.github.com/user";
- public static final String DEFAULT_SCOPE = "user:email";
-
- public GitHubIdentityProvider(OAuth2IdentityProviderConfig config) {
- super(config);
- config.setAuthorizationUrl(AUTH_URL);
- config.setTokenUrl(TOKEN_URL);
- config.setUserInfoUrl(PROFILE_URL);
- }
-
- @Override
- protected BrokeredIdentityContext doGetFederatedIdentity(String accessToken) {
- try {
- JsonNode profile = JsonSimpleHttp.asJson(SimpleHttp.doGet(PROFILE_URL).header("Authorization", "Bearer " + accessToken));
-
- BrokeredIdentityContext user = new BrokeredIdentityContext(getJsonProperty(profile, "id"));
-
- String username = getJsonProperty(profile, "login");
- user.setUsername(username);
- user.setName(getJsonProperty(profile, "name"));
- user.setEmail(getJsonProperty(profile, "email"));
- user.setIdpConfig(getConfig());
- user.setIdp(this);
-
- return user;
- } catch (Exception e) {
- throw new IdentityBrokerException("Could not obtain user profile from github.", e);
- }
- }
-
- @Override
- protected String getDefaultScopes() {
- return DEFAULT_SCOPE;
- }
+ public static final String AUTH_URL = "https://github.com/login/oauth/authorize";
+ public static final String TOKEN_URL = "https://github.com/login/oauth/access_token";
+ public static final String PROFILE_URL = "https://api.github.com/user";
+ public static final String DEFAULT_SCOPE = "user:email";
+
+ public GitHubIdentityProvider(OAuth2IdentityProviderConfig config) {
+ super(config);
+ config.setAuthorizationUrl(AUTH_URL);
+ config.setTokenUrl(TOKEN_URL);
+ config.setUserInfoUrl(PROFILE_URL);
+ }
+
+ @Override
+ protected BrokeredIdentityContext doGetFederatedIdentity(String accessToken) {
+ try {
+ JsonNode profile = JsonSimpleHttp.asJson(SimpleHttp.doGet(PROFILE_URL).header("Authorization", "Bearer " + accessToken));
+
+ BrokeredIdentityContext user = new BrokeredIdentityContext(getJsonProperty(profile, "id"));
+
+ String username = getJsonProperty(profile, "login");
+ user.setUsername(username);
+ user.setName(getJsonProperty(profile, "name"));
+ user.setEmail(getJsonProperty(profile, "email"));
+ user.setIdpConfig(getConfig());
+ user.setIdp(this);
+
+ AbstractJsonUserAttributeMapper.storeUserProfileForMapper(user, profile, getConfig().getAlias());
+
+ return user;
+ } catch (Exception e) {
+ throw new IdentityBrokerException("Could not obtain user profile from github.", e);
+ }
+ }
+
+ @Override
+ protected String getDefaultScopes() {
+ return DEFAULT_SCOPE;
+ }
}
diff --git a/social/github/src/main/java/org/keycloak/social/github/GitHubUserAttributeMapper.java b/social/github/src/main/java/org/keycloak/social/github/GitHubUserAttributeMapper.java
new file mode 100644
index 0000000..b4a6359
--- /dev/null
+++ b/social/github/src/main/java/org/keycloak/social/github/GitHubUserAttributeMapper.java
@@ -0,0 +1,29 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2015 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @authors tag. All rights reserved.
+ */
+package org.keycloak.social.github;
+
+import org.keycloak.broker.oidc.mappers.AbstractJsonUserAttributeMapper;
+
+/**
+ * User attribute mapper.
+ *
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class GitHubUserAttributeMapper extends AbstractJsonUserAttributeMapper {
+
+ private static final String[] cp = new String[] { GitHubIdentityProviderFactory.PROVIDER_ID };
+
+ @Override
+ public String[] getCompatibleProviders() {
+ return cp;
+ }
+
+ @Override
+ public String getId() {
+ return "github-user-attribute-mapper";
+ }
+
+}
diff --git a/social/github/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper b/social/github/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper
new file mode 100755
index 0000000..25972f6
--- /dev/null
+++ b/social/github/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper
@@ -0,0 +1 @@
+org.keycloak.social.github.GitHubUserAttributeMapper
\ No newline at end of file
social/google/pom.xml 2(+1 -1)
diff --git a/social/google/pom.xml b/social/google/pom.xml
index 8689171..2a9f40e 100755
--- a/social/google/pom.xml
+++ b/social/google/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-social-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/social/google/src/main/java/org/keycloak/social/google/GoogleUserAttributeMapper.java b/social/google/src/main/java/org/keycloak/social/google/GoogleUserAttributeMapper.java
new file mode 100644
index 0000000..a2e7ef2
--- /dev/null
+++ b/social/google/src/main/java/org/keycloak/social/google/GoogleUserAttributeMapper.java
@@ -0,0 +1,29 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2015 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @authors tag. All rights reserved.
+ */
+package org.keycloak.social.google;
+
+import org.keycloak.broker.oidc.mappers.AbstractJsonUserAttributeMapper;
+
+/**
+ * User attribute mapper.
+ *
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class GoogleUserAttributeMapper extends AbstractJsonUserAttributeMapper {
+
+ private static final String[] cp = new String[] { GoogleIdentityProviderFactory.PROVIDER_ID };
+
+ @Override
+ public String[] getCompatibleProviders() {
+ return cp;
+ }
+
+ @Override
+ public String getId() {
+ return "google-user-attribute-mapper";
+ }
+
+}
diff --git a/social/google/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper b/social/google/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper
new file mode 100755
index 0000000..f0a3d86
--- /dev/null
+++ b/social/google/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper
@@ -0,0 +1 @@
+org.keycloak.social.google.GoogleUserAttributeMapper
\ No newline at end of file
social/linkedin/pom.xml 2(+1 -1)
diff --git a/social/linkedin/pom.xml b/social/linkedin/pom.xml
index 01232bd..b6c80c5 100755
--- a/social/linkedin/pom.xml
+++ b/social/linkedin/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-social-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/social/linkedin/src/main/java/org/keycloak/social/linkedin/LinkedInIdentityProvider.java b/social/linkedin/src/main/java/org/keycloak/social/linkedin/LinkedInIdentityProvider.java
index d6b7108..2f439c2 100755
--- a/social/linkedin/src/main/java/org/keycloak/social/linkedin/LinkedInIdentityProvider.java
+++ b/social/linkedin/src/main/java/org/keycloak/social/linkedin/LinkedInIdentityProvider.java
@@ -25,10 +25,11 @@ import org.codehaus.jackson.JsonNode;
import org.jboss.logging.Logger;
import org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider;
import org.keycloak.broker.oidc.OAuth2IdentityProviderConfig;
+import org.keycloak.broker.oidc.mappers.AbstractJsonUserAttributeMapper;
import org.keycloak.broker.oidc.util.JsonSimpleHttp;
-import org.keycloak.broker.provider.util.SimpleHttp;
import org.keycloak.broker.provider.BrokeredIdentityContext;
import org.keycloak.broker.provider.IdentityBrokerException;
+import org.keycloak.broker.provider.util.SimpleHttp;
import org.keycloak.social.SocialIdentityProvider;
/**
@@ -58,16 +59,18 @@ public class LinkedInIdentityProvider extends AbstractOAuth2IdentityProvider imp
try {
JsonNode profile = JsonSimpleHttp.asJson(SimpleHttp.doGet(PROFILE_URL).header("Authorization", "Bearer " + accessToken));
- BrokeredIdentityContext user = new BrokeredIdentityContext(getJsonProperty(profile, "id"));
+ BrokeredIdentityContext user = new BrokeredIdentityContext(getJsonProperty(profile, "id"));
- String username = extractUsernameFromProfileURL(getJsonProperty(profile, "publicProfileUrl"));
- user.setUsername(username);
+ String username = extractUsernameFromProfileURL(getJsonProperty(profile, "publicProfileUrl"));
+ user.setUsername(username);
user.setName(getJsonProperty(profile, "formattedName"));
user.setEmail(getJsonProperty(profile, "emailAddress"));
- user.setIdpConfig(getConfig());
- user.setIdp(this);
+ user.setIdpConfig(getConfig());
+ user.setIdp(this);
+
+ AbstractJsonUserAttributeMapper.storeUserProfileForMapper(user, profile, getConfig().getAlias());
- return user;
+ return user;
} catch (Exception e) {
throw new IdentityBrokerException("Could not obtain user profile from linkedIn.", e);
}
diff --git a/social/linkedin/src/main/java/org/keycloak/social/linkedin/LinkedInUserAttributeMapper.java b/social/linkedin/src/main/java/org/keycloak/social/linkedin/LinkedInUserAttributeMapper.java
new file mode 100644
index 0000000..9bc89e7
--- /dev/null
+++ b/social/linkedin/src/main/java/org/keycloak/social/linkedin/LinkedInUserAttributeMapper.java
@@ -0,0 +1,29 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2015 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @authors tag. All rights reserved.
+ */
+package org.keycloak.social.linkedin;
+
+import org.keycloak.broker.oidc.mappers.AbstractJsonUserAttributeMapper;
+
+/**
+ * User attribute mapper.
+ *
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class LinkedInUserAttributeMapper extends AbstractJsonUserAttributeMapper {
+
+ private static final String[] cp = new String[] { LinkedInIdentityProviderFactory.PROVIDER_ID };
+
+ @Override
+ public String[] getCompatibleProviders() {
+ return cp;
+ }
+
+ @Override
+ public String getId() {
+ return "linkedin-user-attribute-mapper";
+ }
+
+}
diff --git a/social/linkedin/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper b/social/linkedin/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper
new file mode 100755
index 0000000..61b7730
--- /dev/null
+++ b/social/linkedin/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper
@@ -0,0 +1 @@
+org.keycloak.social.linkedin.LinkedInUserAttributeMapper
\ No newline at end of file
social/pom.xml 2(+1 -1)
diff --git a/social/pom.xml b/social/pom.xml
index 557d449..ab75ead 100755
--- a/social/pom.xml
+++ b/social/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
social/stackoverflow/pom.xml 2(+1 -1)
diff --git a/social/stackoverflow/pom.xml b/social/stackoverflow/pom.xml
index 97e4dbf..f504769 100755
--- a/social/stackoverflow/pom.xml
+++ b/social/stackoverflow/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-social-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/social/stackoverflow/src/main/java/org/keycloak/social/stackoverflow/StackoverflowIdentityProvider.java b/social/stackoverflow/src/main/java/org/keycloak/social/stackoverflow/StackoverflowIdentityProvider.java
index 280753b..ab9b97a 100755
--- a/social/stackoverflow/src/main/java/org/keycloak/social/stackoverflow/StackoverflowIdentityProvider.java
+++ b/social/stackoverflow/src/main/java/org/keycloak/social/stackoverflow/StackoverflowIdentityProvider.java
@@ -26,10 +26,11 @@ import java.util.HashMap;
import org.codehaus.jackson.JsonNode;
import org.jboss.logging.Logger;
import org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider;
+import org.keycloak.broker.oidc.mappers.AbstractJsonUserAttributeMapper;
import org.keycloak.broker.oidc.util.JsonSimpleHttp;
-import org.keycloak.broker.provider.util.SimpleHttp;
import org.keycloak.broker.provider.BrokeredIdentityContext;
import org.keycloak.broker.provider.IdentityBrokerException;
+import org.keycloak.broker.provider.util.SimpleHttp;
import org.keycloak.social.SocialIdentityProvider;
/**
@@ -37,8 +38,7 @@ import org.keycloak.social.SocialIdentityProvider;
*
* @author Vlastimil Elias (velias at redhat dot com)
*/
-public class StackoverflowIdentityProvider extends AbstractOAuth2IdentityProvider<StackOverflowIdentityProviderConfig>
- implements SocialIdentityProvider<StackOverflowIdentityProviderConfig> {
+public class StackoverflowIdentityProvider extends AbstractOAuth2IdentityProvider<StackOverflowIdentityProviderConfig> implements SocialIdentityProvider<StackOverflowIdentityProviderConfig> {
private static final Logger log = Logger.getLogger(StackoverflowIdentityProvider.class);
@@ -54,8 +54,6 @@ public class StackoverflowIdentityProvider extends AbstractOAuth2IdentityProvide
config.setUserInfoUrl(PROFILE_URL);
}
-
-
@Override
protected BrokeredIdentityContext doGetFederatedIdentity(String accessToken) {
log.debug("doGetFederatedIdentity()");
@@ -67,18 +65,19 @@ public class StackoverflowIdentityProvider extends AbstractOAuth2IdentityProvide
}
JsonNode profile = JsonSimpleHttp.asJson(SimpleHttp.doGet(URL)).get("items").get(0);
- BrokeredIdentityContext user = new BrokeredIdentityContext(getJsonProperty(profile, "user_id"));
+ BrokeredIdentityContext user = new BrokeredIdentityContext(getJsonProperty(profile, "user_id"));
- String username = extractUsernameFromProfileURL(getJsonProperty(profile, "link"));
- user.setUsername(username);
+ String username = extractUsernameFromProfileURL(getJsonProperty(profile, "link"));
+ user.setUsername(username);
user.setName(unescapeHtml3(getJsonProperty(profile, "display_name")));
// email is not provided
// user.setEmail(getJsonProperty(profile, "email"));
- user.setIdpConfig(getConfig());
- user.setIdp(this);
+ user.setIdpConfig(getConfig());
+ user.setIdp(this);
+ AbstractJsonUserAttributeMapper.storeUserProfileForMapper(user, profile, getConfig().getAlias());
- return user;
+ return user;
} catch (Exception e) {
throw new IdentityBrokerException("Could not obtain user profile from Stackoverflow: " + e.getMessage(), e);
}
diff --git a/social/stackoverflow/src/main/java/org/keycloak/social/stackoverflow/StackoverflowUserAttributeMapper.java b/social/stackoverflow/src/main/java/org/keycloak/social/stackoverflow/StackoverflowUserAttributeMapper.java
new file mode 100644
index 0000000..5fe3b97
--- /dev/null
+++ b/social/stackoverflow/src/main/java/org/keycloak/social/stackoverflow/StackoverflowUserAttributeMapper.java
@@ -0,0 +1,29 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2015 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @authors tag. All rights reserved.
+ */
+package org.keycloak.social.stackoverflow;
+
+import org.keycloak.broker.oidc.mappers.AbstractJsonUserAttributeMapper;
+
+/**
+ * User attribute mapper.
+ *
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class StackoverflowUserAttributeMapper extends AbstractJsonUserAttributeMapper {
+
+ private static final String[] cp = new String[] { StackoverflowIdentityProviderFactory.PROVIDER_ID };
+
+ @Override
+ public String[] getCompatibleProviders() {
+ return cp;
+ }
+
+ @Override
+ public String getId() {
+ return "stackoverflow-user-attribute-mapper";
+ }
+
+}
diff --git a/social/stackoverflow/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper b/social/stackoverflow/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper
new file mode 100755
index 0000000..b7a3a5e
--- /dev/null
+++ b/social/stackoverflow/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderMapper
@@ -0,0 +1 @@
+org.keycloak.social.stackoverflow.StackoverflowUserAttributeMapper
\ No newline at end of file
social/twitter/pom.xml 2(+1 -1)
diff --git a/social/twitter/pom.xml b/social/twitter/pom.xml
index 43943fd..b2bc524 100755
--- a/social/twitter/pom.xml
+++ b/social/twitter/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-social-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
testsuite/docker-cluster/pom.xml 6(+3 -3)
diff --git a/testsuite/docker-cluster/pom.xml b/testsuite/docker-cluster/pom.xml
index bfe532b..6de2d2c 100755
--- a/testsuite/docker-cluster/pom.xml
+++ b/testsuite/docker-cluster/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-testsuite-pom</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@@ -21,7 +21,7 @@
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
- <artifactId>keycloak-wildfly-adapter-dist</artifactId>
+ <artifactId>keycloak-wf8-adapter-dist</artifactId>
<type>zip</type>
</dependency>
<dependency>
@@ -69,7 +69,7 @@
</artifactItem>
<artifactItem>
<groupId>org.keycloak</groupId>
- <artifactId>keycloak-wildfly-adapter-dist</artifactId>
+ <artifactId>keycloak-wf8-adapter-dist</artifactId>
<type>zip</type>
<version>${project.version}</version>
<outputDirectory>${project.build.directory}/wildfly-adapter</outputDirectory>
testsuite/integration/pom.xml 4(+3 -1)
diff --git a/testsuite/integration/pom.xml b/testsuite/integration/pom.xml
index 6b5051a..98bdf98 100755
--- a/testsuite/integration/pom.xml
+++ b/testsuite/integration/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-testsuite-pom</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -381,6 +381,8 @@
<keycloak.user.provider>jpa</keycloak.user.provider>
<keycloak.eventsStore.provider>jpa</keycloak.eventsStore.provider>
<keycloak.userSessions.provider>jpa</keycloak.userSessions.provider>
+
+ <keycloak.liquibase.logging.level>trace</keycloak.liquibase.logging.level>
</systemPropertyVariables>
</configuration>
</plugin>
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
index 45200c9..04db4d1 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
@@ -243,6 +243,9 @@ public class AccountTest {
Assert.assertEquals("Invalid username or password.", loginPage.getError());
+ events.expectLogin().session((String) null).error("invalid_user_credentials")
+ .removeDetail(Details.CONSENT)
+ .assertEvent();
events.expectLogin().session((String) null).user(userId).error("invalid_user_credentials").assertEvent();
loginPage.open();
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/AssertEvents.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/AssertEvents.java
index ea8fab2..f180530 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/AssertEvents.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/AssertEvents.java
@@ -116,7 +116,7 @@ public class AssertEvents implements TestRule, EventListenerProviderFactory {
}
public ExpectedEvent expectRequiredAction(EventType event) {
- return expectLogin().event(event).session(isUUID());
+ return expectLogin().event(event).removeDetail(Details.CONSENT).session(isUUID());
}
public ExpectedEvent expectLogin() {
@@ -126,6 +126,7 @@ public class AssertEvents implements TestRule, EventListenerProviderFactory {
//.detail(Details.AUTH_METHOD, OIDCLoginProtocol.LOGIN_PROTOCOL)
//.detail(Details.AUTH_TYPE, AuthorizationEndpoint.CODE_AUTH_TYPE)
.detail(Details.REDIRECT_URI, DEFAULT_REDIRECT_URI)
+ .detail(Details.CONSENT, Details.CONSENT_VALUE_NO_CONSENT_REQUIRED)
.session(isUUID());
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/SAMLKeyCloakServerBrokerWithSignatureTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/SAMLKeyCloakServerBrokerWithSignatureTest.java
index 34c10d5..b94f4df 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/SAMLKeyCloakServerBrokerWithSignatureTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/SAMLKeyCloakServerBrokerWithSignatureTest.java
@@ -45,6 +45,11 @@ public class SAMLKeyCloakServerBrokerWithSignatureTest extends AbstractIdentityP
}
};
+ // @Test
+ public void testSleep() throws Exception {
+ Thread.sleep(100000000);
+ }
+
@Override
protected String getProviderId() {
return "kc-saml-signed-idp";
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/FederationProvidersIntegrationTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/FederationProvidersIntegrationTest.java
index c384651..4ed0d28 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/FederationProvidersIntegrationTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/FederationProvidersIntegrationTest.java
@@ -247,7 +247,7 @@ public class FederationProvidersIntegrationTest {
loginPage.clickRegister();
registerPage.assertCurrent();
- registerPage.register("firstName", "lastName", "email2@check.cz", "registerUserSuccess2", "Password1", "Password1", "non-LDAP-Mapped street", null, null, "78910", null);
+ registerPage.register("firstName", "lastName", "email2@check.cz", "registerUserSuccess2", "Password1", "Password1");
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
KeycloakSession session = keycloakRule.startSession();
@@ -257,8 +257,6 @@ public class FederationProvidersIntegrationTest {
Assert.assertNotNull(user);
Assert.assertNotNull(user.getFederationLink());
Assert.assertEquals(user.getFederationLink(), ldapModel.getId());
- Assert.assertEquals("78910", user.getAttribute("postal_code"));
- Assert.assertEquals("non-LDAP-Mapped street", user.getAttribute("street"));
} finally {
keycloakRule.stopSession(session, false);
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java
index d84b8f9..c2c9fe0 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java
@@ -1,443 +1,461 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2012, 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.keycloak.testsuite.forms;
-
-import org.junit.Assert;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.keycloak.OAuth2Constants;
-import org.keycloak.events.Details;
-import org.keycloak.events.Event;
-import org.keycloak.events.EventType;
-import org.keycloak.models.BrowserSecurityHeaders;
-import org.keycloak.models.PasswordPolicy;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.UserCredentialModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.representations.idm.CredentialRepresentation;
-import org.keycloak.services.managers.RealmManager;
-import org.keycloak.testsuite.AssertEvents;
-import org.keycloak.testsuite.OAuthClient;
-import org.keycloak.testsuite.pages.AppPage;
-import org.keycloak.testsuite.pages.AppPage.RequestType;
-import org.keycloak.testsuite.pages.ErrorPage;
-import org.keycloak.testsuite.pages.LoginPage;
-import org.keycloak.testsuite.pages.LoginPasswordUpdatePage;
-import org.keycloak.testsuite.rule.KeycloakRule;
-import org.keycloak.testsuite.rule.WebResource;
-import org.keycloak.testsuite.rule.WebRule;
-import org.keycloak.util.Time;
-import org.openqa.selenium.WebDriver;
-
-import javax.ws.rs.client.Client;
-import javax.ws.rs.client.ClientBuilder;
-import javax.ws.rs.core.Response;
-
-import java.util.Map;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-/**
- * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
- */
-public class LoginTest {
-
- @ClassRule
- public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
- @Override
- public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- UserModel user = manager.getSession().users().addUser(appRealm, "login-test");
- user.setEmail("login@test.com");
- user.setEnabled(true);
-
- userId = user.getId();
-
- UserCredentialModel creds = new UserCredentialModel();
- creds.setType(CredentialRepresentation.PASSWORD);
- creds.setValue("password");
-
- user.updateCredential(creds);
- }
- });
-
- @Rule
- public AssertEvents events = new AssertEvents(keycloakRule);
-
- @Rule
- public WebRule webRule = new WebRule(this);
-
- @WebResource
- protected OAuthClient oauth;
-
- @WebResource
- protected WebDriver driver;
-
- @WebResource
- protected AppPage appPage;
-
- @WebResource
- protected LoginPage loginPage;
-
- @WebResource
- protected ErrorPage errorPage;
-
- @WebResource
- protected LoginPasswordUpdatePage updatePasswordPage;
-
- private static String userId;
-
- @Test
- public void testBrowserSecurityHeaders() {
- Client client = ClientBuilder.newClient();
- Response response = client.target(oauth.getLoginFormUrl()).request().get();
- Assert.assertEquals(200, response.getStatus());
- for (Map.Entry<String, String> entry : BrowserSecurityHeaders.defaultHeaders.entrySet()) {
- String headerName = BrowserSecurityHeaders.headerAttributeMap.get(entry.getKey());
- String headerValue = response.getHeaderString(headerName);
- Assert.assertNotNull(headerValue);
- Assert.assertEquals(headerValue, entry.getValue());
- }
- response.close();
- }
-
- @Test
- public void loginInvalidPassword() {
- loginPage.open();
- loginPage.login("login-test", "invalid");
-
- loginPage.assertCurrent();
-
- Assert.assertEquals("Invalid username or password.", loginPage.getError());
-
- events.expectLogin().user(userId).session((String) null).error("invalid_user_credentials").detail(Details.USERNAME, "login-test").assertEvent();
- }
-
- @Test
- public void loginInvalidPasswordDisabledUser() {
- keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
- @Override
- public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- session.users().getUserByUsername("login-test", appRealm).setEnabled(false);
- }
- });
-
- try {
- loginPage.open();
- loginPage.login("login-test", "invalid");
-
- loginPage.assertCurrent();
-
- Assert.assertEquals("Account is disabled, contact admin.", loginPage.getError());
-
- events.expectLogin().user(userId).session((String) null).error("user_disabled").detail(Details.USERNAME, "login-test").assertEvent();
- } finally {
- keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
- @Override
- public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- session.users().getUserByUsername("login-test", appRealm).setEnabled(true);
- }
- });
- }
- }
-
- @Test
- public void loginDisabledUser() {
- keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
- @Override
- public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- session.users().getUserByUsername("login-test", appRealm).setEnabled(false);
- }
- });
-
- try {
- loginPage.open();
- loginPage.login("login-test", "password");
-
- loginPage.assertCurrent();
-
- Assert.assertEquals("Account is disabled, contact admin.", loginPage.getError());
-
- events.expectLogin().user(userId).session((String) null).error("user_disabled").detail(Details.USERNAME, "login-test").assertEvent();
- } finally {
- keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
- @Override
- public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- session.users().getUserByUsername("login-test", appRealm).setEnabled(true);
- }
- });
- }
- }
-
- @Test
- public void loginInvalidUsername() {
- loginPage.open();
- loginPage.login("invalid", "password");
-
- loginPage.assertCurrent();
-
- Assert.assertEquals("Invalid username or password.", loginPage.getError());
-
- events.expectLogin().user((String) null).session((String) null).error("user_not_found").detail(Details.USERNAME, "invalid").assertEvent();
- }
-
- @Test
- public void loginSuccess() {
- loginPage.open();
- loginPage.login("login-test", "password");
-
- Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
- Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
-
- events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent();
- }
-
- @Test
- public void loginPromptNone() {
- driver.navigate().to(oauth.getLoginFormUrl().toString() + "&prompt=none");
-
- assertFalse(loginPage.isCurrent());
- assertTrue(appPage.isCurrent());
-
- loginPage.open();
- loginPage.login("login-test", "password");
- Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
-
- events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent();
-
- driver.navigate().to(oauth.getLoginFormUrl().toString() + "&prompt=none");
- Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
-
- events.expectLogin().user(userId).removeDetail(Details.USERNAME).assertEvent();
- }
-
- @Test
- public void loginWithForcePasswordChangePolicy() {
- keycloakRule.update(new KeycloakRule.KeycloakSetup() {
- @Override
- public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- appRealm.setPasswordPolicy(new PasswordPolicy("forceExpiredPasswordChange(1)"));
- }
- });
-
- try {
- // Setting offset to more than one day to force password update
- // elapsedTime > timeToExpire
- Time.setOffset(86405);
-
- loginPage.open();
-
- loginPage.login("login-test", "password");
-
- updatePasswordPage.assertCurrent();
-
- updatePasswordPage.changePassword("updatedPassword", "updatedPassword");
-
- events.expectRequiredAction(EventType.UPDATE_PASSWORD).user(userId).detail(Details.USERNAME, "login-test").assertEvent();
-
- assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
-
- events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent();
-
- } finally {
- keycloakRule.update(new KeycloakRule.KeycloakSetup() {
- @Override
- public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- appRealm.setPasswordPolicy(new PasswordPolicy(null));
-
- UserModel user = manager.getSession().users().getUserByUsername("login-test", appRealm);
- UserCredentialModel cred = new UserCredentialModel();
- cred.setType(CredentialRepresentation.PASSWORD);
- cred.setValue("password");
- user.updateCredential(cred);
- }
- });
- Time.setOffset(0);
- }
- }
-
- @Test
- public void loginWithoutForcePasswordChangePolicy() {
- keycloakRule.update(new KeycloakRule.KeycloakSetup() {
- @Override
- public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- appRealm.setPasswordPolicy(new PasswordPolicy("forceExpiredPasswordChange(1)"));
- }
- });
-
- try {
- // Setting offset to less than one day to avoid forced password update
- // elapsedTime < timeToExpire
- Time.setOffset(86205);
-
- loginPage.open();
-
- loginPage.login("login-test", "password");
-
- Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
- Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
-
- events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent();
-
- } finally {
- keycloakRule.update(new KeycloakRule.KeycloakSetup() {
- @Override
- public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- appRealm.setPasswordPolicy(new PasswordPolicy(null));
- }
- });
- Time.setOffset(0);
- }
- }
-
- @Test
- public void loginNoTimeoutWithLongWait() {
- try {
- loginPage.open();
-
- Time.setOffset(1700);
-
- loginPage.login("login-test", "password");
-
- events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent().getSessionId();
- } finally {
- Time.setOffset(0);
- }
- }
-
- @Test
- public void loginTimeout() {
- try {
- loginPage.open();
-
- Time.setOffset(1850);
-
- loginPage.login("login-test", "password");
-
- events.expectLogin().clearDetails().detail(Details.CODE_ID, AssertEvents.isCodeId()).user((String) null).session((String) null).error("expired_code").assertEvent().getSessionId();
- } finally {
- Time.setOffset(0);
- }
- }
-
- @Test
- public void loginLoginHint() {
- String loginFormUrl = oauth.getLoginFormUrl() + "&login_hint=login-test";
- driver.navigate().to(loginFormUrl);
-
- Assert.assertEquals("login-test", loginPage.getUsername());
- loginPage.login("password");
-
- Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
- Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
-
- events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent();
- }
-
- @Test
- public void loginWithEmailSuccess() {
- loginPage.open();
- loginPage.login("login@test.com", "password");
-
- Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
- Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
-
- events.expectLogin().user(userId).assertEvent();
- }
-
- @Test
- public void loginWithRememberMe() {
- keycloakRule.update(new KeycloakRule.KeycloakSetup() {
- @Override
- public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- appRealm.setRememberMe(true);
- }
- });
-
- try {
- loginPage.open();
- assertFalse(loginPage.isRememberMeChecked());
- loginPage.setRememberMe(true);
- assertTrue(loginPage.isRememberMeChecked());
- loginPage.login("login-test", "password");
-
- Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
- Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
- Event loginEvent = events.expectLogin().user(userId)
- .detail(Details.USERNAME, "login-test")
- .detail(Details.REMEMBER_ME, "true")
- .assertEvent();
- String sessionId = loginEvent.getSessionId();
-
- // Expire session
- keycloakRule.removeUserSession(sessionId);
-
- // Assert rememberMe checked and username/email prefilled
- loginPage.open();
- assertTrue(loginPage.isRememberMeChecked());
- Assert.assertEquals("login-test", loginPage.getUsername());
-
- loginPage.setRememberMe(false);
- } finally {
- keycloakRule.update(new KeycloakRule.KeycloakSetup() {
- @Override
- public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- appRealm.setRememberMe(false);
- }
- });
- }
- }
-
- @Test
- public void loginCancel() {
- loginPage.open();
- loginPage.cancel();
-
- Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
- Assert.assertEquals("access_denied", oauth.getCurrentQuery().get(OAuth2Constants.ERROR));
-
- events.expectLogin().error("rejected_by_user").user((String) null).session((String) null).removeDetail(Details.USERNAME).assertEvent();
- }
-
- // KEYCLOAK-1037
- @Test
- public void loginExpiredCode() {
- try {
- loginPage.open();
- Time.setOffset(5000);
- loginPage.login("login@test.com", "password");
-
- //loginPage.assertCurrent();
- errorPage.assertCurrent();
-
- //Assert.assertEquals("Login timeout. Please login again.", loginPage.getError());
-
- events.expectLogin().user((String) null).session((String) null).error("expired_code").clearDetails().detail(Details.CODE_ID, AssertEvents.isCodeId()).assertEvent();
-
- } finally {
- Time.setOffset(0);
- }
- }
-
-}
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2012, 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.keycloak.testsuite.forms;
+
+import org.junit.Assert;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.keycloak.OAuth2Constants;
+import org.keycloak.events.Details;
+import org.keycloak.events.Event;
+import org.keycloak.events.EventType;
+import org.keycloak.models.BrowserSecurityHeaders;
+import org.keycloak.models.PasswordPolicy;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserCredentialModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.representations.idm.CredentialRepresentation;
+import org.keycloak.services.managers.RealmManager;
+import org.keycloak.testsuite.AssertEvents;
+import org.keycloak.testsuite.OAuthClient;
+import org.keycloak.testsuite.pages.AppPage;
+import org.keycloak.testsuite.pages.AppPage.RequestType;
+import org.keycloak.testsuite.pages.ErrorPage;
+import org.keycloak.testsuite.pages.LoginPage;
+import org.keycloak.testsuite.pages.LoginPasswordUpdatePage;
+import org.keycloak.testsuite.rule.KeycloakRule;
+import org.keycloak.testsuite.rule.WebResource;
+import org.keycloak.testsuite.rule.WebRule;
+import org.keycloak.util.Time;
+import org.openqa.selenium.WebDriver;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.core.Response;
+
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class LoginTest {
+
+ @ClassRule
+ public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
+ @Override
+ public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+ UserModel user = manager.getSession().users().addUser(appRealm, "login-test");
+ user.setEmail("login@test.com");
+ user.setEnabled(true);
+
+ userId = user.getId();
+
+ UserCredentialModel creds = new UserCredentialModel();
+ creds.setType(CredentialRepresentation.PASSWORD);
+ creds.setValue("password");
+
+ user.updateCredential(creds);
+ }
+ });
+
+ @Rule
+ public AssertEvents events = new AssertEvents(keycloakRule);
+
+ @Rule
+ public WebRule webRule = new WebRule(this);
+
+ @WebResource
+ protected OAuthClient oauth;
+
+ @WebResource
+ protected WebDriver driver;
+
+ @WebResource
+ protected AppPage appPage;
+
+ @WebResource
+ protected LoginPage loginPage;
+
+ @WebResource
+ protected ErrorPage errorPage;
+
+ @WebResource
+ protected LoginPasswordUpdatePage updatePasswordPage;
+
+ private static String userId;
+
+ @Test
+ public void testBrowserSecurityHeaders() {
+ Client client = ClientBuilder.newClient();
+ Response response = client.target(oauth.getLoginFormUrl()).request().get();
+ Assert.assertEquals(200, response.getStatus());
+ for (Map.Entry<String, String> entry : BrowserSecurityHeaders.defaultHeaders.entrySet()) {
+ String headerName = BrowserSecurityHeaders.headerAttributeMap.get(entry.getKey());
+ String headerValue = response.getHeaderString(headerName);
+ Assert.assertNotNull(headerValue);
+ Assert.assertEquals(headerValue, entry.getValue());
+ }
+ response.close();
+ }
+
+ @Test
+ public void loginInvalidPassword() {
+ loginPage.open();
+ loginPage.login("login-test", "invalid");
+
+ loginPage.assertCurrent();
+
+ Assert.assertEquals("Invalid username or password.", loginPage.getError());
+
+ events.expectLogin().user(userId).session((String) null).error("invalid_user_credentials")
+ .detail(Details.USERNAME, "login-test")
+ .removeDetail(Details.CONSENT)
+ .assertEvent();
+ }
+
+ @Test
+ public void loginInvalidPasswordDisabledUser() {
+ keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
+ @Override
+ public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+ session.users().getUserByUsername("login-test", appRealm).setEnabled(false);
+ }
+ });
+
+ try {
+ loginPage.open();
+ loginPage.login("login-test", "invalid");
+
+ loginPage.assertCurrent();
+
+ Assert.assertEquals("Account is disabled, contact admin.", loginPage.getError());
+
+ events.expectLogin().user(userId).session((String) null).error("invalid_user_credentials")
+ .detail(Details.USERNAME, "login-test")
+ .removeDetail(Details.CONSENT)
+ .assertEvent();
+ } finally {
+ keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
+ @Override
+ public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+ session.users().getUserByUsername("login-test", appRealm).setEnabled(true);
+ }
+ });
+ }
+ }
+
+ @Test
+ public void loginDisabledUser() {
+ keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
+ @Override
+ public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+ session.users().getUserByUsername("login-test", appRealm).setEnabled(false);
+ }
+ });
+
+ try {
+ loginPage.open();
+ loginPage.login("login-test", "password");
+
+ loginPage.assertCurrent();
+
+ Assert.assertEquals("Account is disabled, contact admin.", loginPage.getError());
+
+ events.expectLogin().user(userId).session((String) null).error("user_disabled")
+ .detail(Details.USERNAME, "login-test")
+ .removeDetail(Details.CONSENT)
+ .assertEvent();
+ } finally {
+ keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
+ @Override
+ public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+ session.users().getUserByUsername("login-test", appRealm).setEnabled(true);
+ }
+ });
+ }
+ }
+
+ @Test
+ public void loginInvalidUsername() {
+ loginPage.open();
+ loginPage.login("invalid", "password");
+
+ loginPage.assertCurrent();
+
+ Assert.assertEquals("Invalid username or password.", loginPage.getError());
+
+ events.expectLogin().user((String) null).session((String) null).error("user_not_found")
+ .detail(Details.USERNAME, "invalid")
+ .removeDetail(Details.CONSENT)
+ .assertEvent();
+ }
+
+ @Test
+ public void loginSuccess() {
+ loginPage.open();
+ loginPage.login("login-test", "password");
+
+ Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
+ Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
+
+ events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent();
+ }
+
+ @Test
+ public void loginPromptNone() {
+ driver.navigate().to(oauth.getLoginFormUrl().toString() + "&prompt=none");
+
+ assertFalse(loginPage.isCurrent());
+ assertTrue(appPage.isCurrent());
+
+ loginPage.open();
+ loginPage.login("login-test", "password");
+ Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
+
+ events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent();
+
+ driver.navigate().to(oauth.getLoginFormUrl().toString() + "&prompt=none");
+ Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
+
+ events.expectLogin().user(userId).removeDetail(Details.USERNAME).assertEvent();
+ }
+
+ @Test
+ public void loginWithForcePasswordChangePolicy() {
+ keycloakRule.update(new KeycloakRule.KeycloakSetup() {
+ @Override
+ public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+ appRealm.setPasswordPolicy(new PasswordPolicy("forceExpiredPasswordChange(1)"));
+ }
+ });
+
+ try {
+ // Setting offset to more than one day to force password update
+ // elapsedTime > timeToExpire
+ Time.setOffset(86405);
+
+ loginPage.open();
+
+ loginPage.login("login-test", "password");
+
+ updatePasswordPage.assertCurrent();
+
+ updatePasswordPage.changePassword("updatedPassword", "updatedPassword");
+
+ events.expectRequiredAction(EventType.UPDATE_PASSWORD).user(userId).detail(Details.USERNAME, "login-test").assertEvent();
+
+ assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
+
+ events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent();
+
+ } finally {
+ keycloakRule.update(new KeycloakRule.KeycloakSetup() {
+ @Override
+ public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+ appRealm.setPasswordPolicy(new PasswordPolicy(null));
+
+ UserModel user = manager.getSession().users().getUserByUsername("login-test", appRealm);
+ UserCredentialModel cred = new UserCredentialModel();
+ cred.setType(CredentialRepresentation.PASSWORD);
+ cred.setValue("password");
+ user.updateCredential(cred);
+ }
+ });
+ Time.setOffset(0);
+ }
+ }
+
+ @Test
+ public void loginWithoutForcePasswordChangePolicy() {
+ keycloakRule.update(new KeycloakRule.KeycloakSetup() {
+ @Override
+ public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+ appRealm.setPasswordPolicy(new PasswordPolicy("forceExpiredPasswordChange(1)"));
+ }
+ });
+
+ try {
+ // Setting offset to less than one day to avoid forced password update
+ // elapsedTime < timeToExpire
+ Time.setOffset(86205);
+
+ loginPage.open();
+
+ loginPage.login("login-test", "password");
+
+ Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
+ Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
+
+ events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent();
+
+ } finally {
+ keycloakRule.update(new KeycloakRule.KeycloakSetup() {
+ @Override
+ public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+ appRealm.setPasswordPolicy(new PasswordPolicy(null));
+ }
+ });
+ Time.setOffset(0);
+ }
+ }
+
+ @Test
+ public void loginNoTimeoutWithLongWait() {
+ try {
+ loginPage.open();
+
+ Time.setOffset(1700);
+
+ loginPage.login("login-test", "password");
+
+ events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent().getSessionId();
+ } finally {
+ Time.setOffset(0);
+ }
+ }
+
+ @Test
+ public void loginTimeout() {
+ try {
+ loginPage.open();
+
+ Time.setOffset(1850);
+
+ loginPage.login("login-test", "password");
+
+ events.expectLogin().clearDetails().detail(Details.CODE_ID, AssertEvents.isCodeId()).user((String) null).session((String) null).error("expired_code").assertEvent().getSessionId();
+ } finally {
+ Time.setOffset(0);
+ }
+ }
+
+ @Test
+ public void loginLoginHint() {
+ String loginFormUrl = oauth.getLoginFormUrl() + "&login_hint=login-test";
+ driver.navigate().to(loginFormUrl);
+
+ Assert.assertEquals("login-test", loginPage.getUsername());
+ loginPage.login("password");
+
+ Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
+ Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
+
+ events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent();
+ }
+
+ @Test
+ public void loginWithEmailSuccess() {
+ loginPage.open();
+ loginPage.login("login@test.com", "password");
+
+ Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
+ Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
+
+ events.expectLogin().user(userId).assertEvent();
+ }
+
+ @Test
+ public void loginWithRememberMe() {
+ keycloakRule.update(new KeycloakRule.KeycloakSetup() {
+ @Override
+ public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+ appRealm.setRememberMe(true);
+ }
+ });
+
+ try {
+ loginPage.open();
+ assertFalse(loginPage.isRememberMeChecked());
+ loginPage.setRememberMe(true);
+ assertTrue(loginPage.isRememberMeChecked());
+ loginPage.login("login-test", "password");
+
+ Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
+ Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
+ Event loginEvent = events.expectLogin().user(userId)
+ .detail(Details.USERNAME, "login-test")
+ .detail(Details.REMEMBER_ME, "true")
+ .assertEvent();
+ String sessionId = loginEvent.getSessionId();
+
+ // Expire session
+ keycloakRule.removeUserSession(sessionId);
+
+ // Assert rememberMe checked and username/email prefilled
+ loginPage.open();
+ assertTrue(loginPage.isRememberMeChecked());
+ Assert.assertEquals("login-test", loginPage.getUsername());
+
+ loginPage.setRememberMe(false);
+ } finally {
+ keycloakRule.update(new KeycloakRule.KeycloakSetup() {
+ @Override
+ public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+ appRealm.setRememberMe(false);
+ }
+ });
+ }
+ }
+
+ @Test
+ public void loginCancel() {
+ loginPage.open();
+ loginPage.cancel();
+
+ Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
+ Assert.assertEquals("access_denied", oauth.getCurrentQuery().get(OAuth2Constants.ERROR));
+
+ events.expectLogin().error("rejected_by_user").user((String) null).session((String) null)
+ .removeDetail(Details.USERNAME)
+ .removeDetail(Details.CONSENT)
+ .assertEvent();
+ }
+
+ // KEYCLOAK-1037
+ @Test
+ public void loginExpiredCode() {
+ try {
+ loginPage.open();
+ Time.setOffset(5000);
+ loginPage.login("login@test.com", "password");
+
+ //loginPage.assertCurrent();
+ errorPage.assertCurrent();
+
+ //Assert.assertEquals("Login timeout. Please login again.", loginPage.getError());
+
+ events.expectLogin().user((String) null).session((String) null).error("expired_code").clearDetails()
+ .detail(Details.CODE_ID, AssertEvents.isCodeId())
+ .removeDetail(Details.CONSENT)
+ .assertEvent();
+
+ } finally {
+ Time.setOffset(0);
+ }
+ }
+
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java
index 4a86f78..3ea0915 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java
@@ -116,7 +116,9 @@ public class LoginTotpTest {
//loginPage.assertCurrent(); // Invalid authenticator code.
//Assert.assertEquals("Invalid username or password.", loginPage.getError());
- events.expectLogin().error("invalid_user_credentials").session((String) null).assertEvent();
+ events.expectLogin().error("invalid_user_credentials").session((String) null)
+ .removeDetail(Details.CONSENT)
+ .assertEvent();
}
@Test
@@ -142,6 +144,8 @@ public class LoginTotpTest {
Assert.assertEquals("Invalid username or password.", loginPage.getError());
- events.expectLogin().error("invalid_user_credentials").session((String) null).assertEvent();
+ events.expectLogin().error("invalid_user_credentials").session((String) null)
+ .removeDetail(Details.CONSENT)
+ .assertEvent();
}
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/CacheTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/CacheTest.java
index e16ae05..5f8371c 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/CacheTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/CacheTest.java
@@ -5,11 +5,11 @@ import java.util.List;
import org.junit.Assert;
import org.junit.ClassRule;
import org.junit.Test;
-import org.keycloak.models.ClientModel;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.RealmModel;
+import org.keycloak.models.*;
import org.keycloak.testsuite.rule.KeycloakRule;
+import static org.junit.Assert.assertNotNull;
+
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
@@ -26,7 +26,7 @@ public class CacheTest {
KeycloakSession session = kc.startSession();
RealmModel realm = session.realms().getRealmByName("test");
ClientModel testApp = realm.getClientByClientId("test-app");
- Assert.assertNotNull(testApp);
+ assertNotNull(testApp);
appId = testApp.getId();
Assert.assertTrue(testApp.isEnabled());
kc.stopSession(session, true);
@@ -48,7 +48,7 @@ public class CacheTest {
Assert.assertTrue(realm instanceof org.keycloak.models.cache.RealmAdapter);
realm.setAccessCodeLifespanLogin(200);
ClientModel testApp = realm.getClientByClientId("test-app");
- Assert.assertNotNull(testApp);
+ assertNotNull(testApp);
testApp.setEnabled(false);
kc.stopSession(session, true);
}
@@ -65,4 +65,27 @@ public class CacheTest {
}
+
+ @Test
+ public void testAddUserNotAddedToCache() {
+ KeycloakSession session = kc.startSession();
+ try {
+ RealmModel realm = session.realms().getRealmByName("test");
+
+ UserModel user = session.users().addUser(realm, "testAddUserNotAddedToCache");
+ user.setFirstName("firstName");
+ user.addRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP);
+
+ UserSessionModel userSession = session.sessions().createUserSession(realm, user, "testAddUserNotAddedToCache", "127.0.0.1", "auth", false, null, null);
+ UserModel user2 = userSession.getUser();
+
+ user.setLastName("lastName");
+
+ assertNotNull(user2.getLastName());
+ } finally {
+ session.getTransaction().commit();
+ session.close();
+ }
+ }
+
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserFederationModelTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserFederationModelTest.java
index 51fc446..17e0e31 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserFederationModelTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserFederationModelTest.java
@@ -1,5 +1,9 @@
package org.keycloak.testsuite.model;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
@@ -97,6 +101,43 @@ public class UserFederationModelTest extends AbstractModelTest {
commit();
}
+ @Test
+ public void federationProvidersSetTest() {
+ RealmModel realm = realmManager.createRealm("test-realm");
+ UserFederationProviderModel ldapProvider = new UserFederationProviderModel(null, "ldap", new TreeMap<String, String>(), 1, "my-cool-provider", -1, -1, 0);
+ realm.setUserFederationProviders(Arrays.asList(ldapProvider));
+
+ commit();
+
+ realm = realmManager.getRealmByName("test-realm");
+ List<UserFederationProviderModel> fedProviders = realm.getUserFederationProviders();
+ Assert.assertEquals(1, fedProviders.size());
+ ldapProvider = fedProviders.get(0);
+ Set<UserFederationMapperModel> fedMappers = realmManager.getRealmByName("test-realm").getUserFederationMappersByFederationProvider(ldapProvider.getId());
+
+ UserFederationProviderModel dummyProvider = new UserFederationProviderModel(null, "dummy", new TreeMap<String, String>(), 1, "my-cool-provider", -1, -1, 0);
+ try {
+ realm.setUserFederationProviders(Arrays.asList(ldapProvider, dummyProvider));
+ commit();
+ Assert.fail("Don't expect to end here");
+ } catch (ModelDuplicateException expected) {
+ }
+
+ dummyProvider.setDisplayName("my-cool-provider2");
+ realm.setUserFederationProviders(Arrays.asList(ldapProvider, dummyProvider));
+
+ commit();
+
+ realm = realmManager.getRealmByName("test-realm");
+ Assert.assertEquals(fedMappers.size(), realm.getUserFederationMappersByFederationProvider(ldapProvider.getId()).size());
+ realm.setUserFederationProviders(new ArrayList<UserFederationProviderModel>());
+
+ commit();
+
+ realm = realmManager.getRealmByName("test-realm");
+ Assert.assertTrue(realm.getUserFederationMappersByFederationProvider(ldapProvider.getId()).isEmpty());
+ }
+
private UserFederationMapperModel createMapper(String name, String fedProviderId, String... config) {
UserFederationMapperModel mapperModel = new UserFederationMapperModel();
mapperModel.setName(name);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java
index 0a70da0..784318f 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java
@@ -141,6 +141,7 @@ public class AuthorizationCodeTest {
events.expectLogin().error("rejected_by_user").user((String) null).session((String) null)
.removeDetail(Details.USERNAME)
+ .removeDetail(Details.CONSENT)
.detail(Details.REDIRECT_URI, "http://localhost:8081/auth/realms/test/protocol/openid-connect/oauth/oob")
.assertEvent().getDetails().get(Details.CODE_ID);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java
index 1e00be8..bd5ad37 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java
@@ -1,267 +1,287 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2012, 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.keycloak.testsuite.oauth;
-
-import org.junit.Assert;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.keycloak.OAuth2Constants;
-import org.keycloak.constants.KerberosConstants;
-import org.keycloak.events.Details;
-import org.keycloak.events.Event;
-import org.keycloak.events.EventType;
-import org.keycloak.models.ClientModel;
-import org.keycloak.models.ProtocolMapperModel;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.protocol.oidc.OIDCLoginProtocol;
-import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory;
-import org.keycloak.protocol.oidc.mappers.UserSessionNoteMapper;
-import org.keycloak.representations.AccessToken;
-import org.keycloak.services.managers.RealmManager;
-import org.keycloak.testsuite.AssertEvents;
-import org.keycloak.testsuite.OAuthClient;
-import org.keycloak.testsuite.pages.AccountApplicationsPage;
-import org.keycloak.testsuite.pages.AppPage;
-import org.keycloak.testsuite.pages.LoginPage;
-import org.keycloak.testsuite.pages.OAuthGrantPage;
-import org.keycloak.testsuite.rule.KeycloakRule;
-import org.keycloak.testsuite.rule.WebResource;
-import org.keycloak.testsuite.rule.WebRule;
-import org.openqa.selenium.WebDriver;
-
-import java.io.IOException;
-import java.util.Map;
-
-import static org.junit.Assert.assertEquals;
-
-/**
- * @author <a href="mailto:vrockai@redhat.com">Viliam Rockai</a>
- */
-public class OAuthGrantTest {
-
- @ClassRule
- public static KeycloakRule keycloakRule = new KeycloakRule();
-
- @Rule
- public AssertEvents events = new AssertEvents(keycloakRule);
-
- @Rule
- public WebRule webRule = new WebRule(this);
-
- @WebResource
- protected WebDriver driver;
-
- @WebResource
- protected OAuthClient oauth;
-
- @WebResource
- protected LoginPage loginPage;
-
- @WebResource
- protected OAuthGrantPage grantPage;
-
- @WebResource
- protected AccountApplicationsPage accountAppsPage;
-
- @WebResource
- protected AppPage appPage;
-
- private static String ROLE_USER = "Have User privileges";
- private static String ROLE_CUSTOMER = "Have Customer User privileges";
-
- @Test
- public void oauthGrantAcceptTest() {
- oauth.clientId("third-party");
- oauth.doLoginGrant("test-user@localhost", "password");
-
- grantPage.assertCurrent();
- Assert.assertTrue(driver.getPageSource().contains(ROLE_USER));
- Assert.assertTrue(driver.getPageSource().contains(ROLE_CUSTOMER));
-
- grantPage.accept();
-
- Assert.assertTrue(oauth.getCurrentQuery().containsKey(OAuth2Constants.CODE));
-
- Event loginEvent = events.expectLogin().client("third-party").assertEvent();
- String codeId = loginEvent.getDetails().get(Details.CODE_ID);
- String sessionId = loginEvent.getSessionId();
-
- OAuthClient.AccessTokenResponse accessToken = oauth.doAccessTokenRequest(oauth.getCurrentQuery().get(OAuth2Constants.CODE), "password");
-
- String tokenString = accessToken.getAccessToken();
- Assert.assertNotNull(tokenString);
- AccessToken token = oauth.verifyToken(tokenString);
- assertEquals(sessionId, token.getSessionState());
-
- AccessToken.Access realmAccess = token.getRealmAccess();
- assertEquals(1, realmAccess.getRoles().size());
- Assert.assertTrue(realmAccess.isUserInRole("user"));
-
- Map<String,AccessToken.Access> resourceAccess = token.getResourceAccess();
- assertEquals(1, resourceAccess.size());
- assertEquals(1, resourceAccess.get("test-app").getRoles().size());
- Assert.assertTrue(resourceAccess.get("test-app").isUserInRole("customer-user"));
-
- events.expectCodeToToken(codeId, loginEvent.getSessionId()).client("third-party").assertEvent();
-
- accountAppsPage.open();
- accountAppsPage.revokeGrant("third-party");
-
- events.expect(EventType.REVOKE_GRANT)
- .client("account").detail(Details.REVOKED_CLIENT, "third-party").assertEvent();
- }
-
- @Test
- public void oauthGrantCancelTest() {
- oauth.clientId("third-party");
- oauth.doLoginGrant("test-user@localhost", "password");
-
- grantPage.assertCurrent();
- Assert.assertTrue(driver.getPageSource().contains(ROLE_USER));
- Assert.assertTrue(driver.getPageSource().contains(ROLE_CUSTOMER));
-
- grantPage.cancel();
-
- Assert.assertTrue(oauth.getCurrentQuery().containsKey(OAuth2Constants.ERROR));
- assertEquals("access_denied", oauth.getCurrentQuery().get(OAuth2Constants.ERROR));
-
- events.expectLogin().client("third-party").error("rejected_by_user").assertEvent();
- }
-
- @Test
- public void oauthGrantNotShownWhenAlreadyGranted() {
- // Grant permissions on grant screen
- oauth.clientId("third-party");
- oauth.doLoginGrant("test-user@localhost", "password");
-
- grantPage.assertCurrent();
- grantPage.accept();
-
- events.expectLogin().client("third-party").assertEvent();
-
- // Assert permissions granted on Account mgmt. applications page
- accountAppsPage.open();
- AccountApplicationsPage.AppEntry thirdPartyEntry = accountAppsPage.getApplications().get("third-party");
- Assert.assertTrue(thirdPartyEntry.getRolesGranted().contains(ROLE_USER));
- Assert.assertTrue(thirdPartyEntry.getRolesGranted().contains("Have Customer User privileges in test-app"));
- Assert.assertTrue(thirdPartyEntry.getProtocolMappersGranted().contains("Full name"));
- Assert.assertTrue(thirdPartyEntry.getProtocolMappersGranted().contains("Email"));
-
- // Open login form and assert grantPage not shown
- oauth.openLoginForm();
- appPage.assertCurrent();
- events.expectLogin().removeDetail(Details.USERNAME).client("third-party").assertEvent();
-
- // Revoke grant in account mgmt.
- accountAppsPage.open();
- accountAppsPage.revokeGrant("third-party");
-
- events.expect(EventType.REVOKE_GRANT)
- .client("account").detail(Details.REVOKED_CLIENT, "third-party").assertEvent();
-
- // Open login form again and assert grant Page is shown
- oauth.openLoginForm();
- grantPage.assertCurrent();
- Assert.assertTrue(driver.getPageSource().contains(ROLE_USER));
- Assert.assertTrue(driver.getPageSource().contains(ROLE_CUSTOMER));
- }
-
- @Test
- public void oauthGrantAddAnotherRoleAndMapper() {
- // Grant permissions on grant screen
- oauth.clientId("third-party");
- oauth.doLoginGrant("test-user@localhost", "password");
-
- // Add new protocolMapper and role before showing grant page
- keycloakRule.update(new KeycloakRule.KeycloakSetup() {
-
- @Override
- public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- ProtocolMapperModel protocolMapper = UserSessionNoteMapper.createClaimMapper(KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME,
- KerberosConstants.GSS_DELEGATION_CREDENTIAL,
- KerberosConstants.GSS_DELEGATION_CREDENTIAL, "String",
- true, KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME,
- true, false);
-
- ClientModel thirdPartyApp = appRealm.getClientByClientId("third-party");
- thirdPartyApp.addProtocolMapper(protocolMapper);
-
- RoleModel newRole = appRealm.addRole("new-role");
- thirdPartyApp.addScopeMapping(newRole);
- UserModel testUser = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
- testUser.grantRole(newRole);
- }
-
- });
-
- // Confirm grant page
- grantPage.assertCurrent();
- grantPage.accept();
- events.expectLogin().client("third-party").assertEvent();
-
- // Assert new role and protocol mapper not in account mgmt.
- accountAppsPage.open();
- AccountApplicationsPage.AppEntry appEntry = accountAppsPage.getApplications().get("third-party");
- Assert.assertFalse(appEntry.getRolesGranted().contains("new-role"));
- Assert.assertFalse(appEntry.getProtocolMappersGranted().contains(KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME));
-
- // Show grant page another time. Just new role and protocol mapper are on the page
- oauth.openLoginForm();
- grantPage.assertCurrent();
- Assert.assertFalse(driver.getPageSource().contains(ROLE_USER));
- Assert.assertFalse(driver.getPageSource().contains("Full name"));
- Assert.assertTrue(driver.getPageSource().contains("new-role"));
- Assert.assertTrue(driver.getPageSource().contains(KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME));
- grantPage.accept();
- events.expectLogin().client("third-party").assertEvent();
-
- // Go to account mgmt. Everything is granted now
- accountAppsPage.open();
- appEntry = accountAppsPage.getApplications().get("third-party");
- Assert.assertTrue(appEntry.getRolesGranted().contains("new-role"));
- Assert.assertTrue(appEntry.getProtocolMappersGranted().contains(KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME));
-
- // Revoke
- accountAppsPage.revokeGrant("third-party");
- events.expect(EventType.REVOKE_GRANT)
- .client("account").detail(Details.REVOKED_CLIENT, "third-party").assertEvent();
-
- // Cleanup
- keycloakRule.update(new KeycloakRule.KeycloakSetup() {
-
- @Override
- public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- ClientModel thirdPartyApp = appRealm.getClientByClientId("third-party");
- ProtocolMapperModel gssMapper = thirdPartyApp.getProtocolMapperByName(OIDCLoginProtocol.LOGIN_PROTOCOL, KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME);
- thirdPartyApp.removeProtocolMapper(gssMapper);
-
- RoleModel newRole = appRealm.getRole("new-role");
- appRealm.removeRole(newRole);
- }
-
- });
- }
-
-}
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2012, 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.keycloak.testsuite.oauth;
+
+import org.junit.Assert;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.keycloak.OAuth2Constants;
+import org.keycloak.constants.KerberosConstants;
+import org.keycloak.events.Details;
+import org.keycloak.events.Event;
+import org.keycloak.events.EventType;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.ProtocolMapperModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.protocol.oidc.OIDCLoginProtocol;
+import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory;
+import org.keycloak.protocol.oidc.mappers.UserSessionNoteMapper;
+import org.keycloak.representations.AccessToken;
+import org.keycloak.services.managers.RealmManager;
+import org.keycloak.testsuite.AssertEvents;
+import org.keycloak.testsuite.OAuthClient;
+import org.keycloak.testsuite.pages.AccountApplicationsPage;
+import org.keycloak.testsuite.pages.AppPage;
+import org.keycloak.testsuite.pages.LoginPage;
+import org.keycloak.testsuite.pages.OAuthGrantPage;
+import org.keycloak.testsuite.rule.KeycloakRule;
+import org.keycloak.testsuite.rule.WebResource;
+import org.keycloak.testsuite.rule.WebRule;
+import org.openqa.selenium.WebDriver;
+
+import java.io.IOException;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author <a href="mailto:vrockai@redhat.com">Viliam Rockai</a>
+ */
+public class OAuthGrantTest {
+
+ @ClassRule
+ public static KeycloakRule keycloakRule = new KeycloakRule();
+
+ @Rule
+ public AssertEvents events = new AssertEvents(keycloakRule);
+
+ @Rule
+ public WebRule webRule = new WebRule(this);
+
+ @WebResource
+ protected WebDriver driver;
+
+ @WebResource
+ protected OAuthClient oauth;
+
+ @WebResource
+ protected LoginPage loginPage;
+
+ @WebResource
+ protected OAuthGrantPage grantPage;
+
+ @WebResource
+ protected AccountApplicationsPage accountAppsPage;
+
+ @WebResource
+ protected AppPage appPage;
+
+ private static String ROLE_USER = "Have User privileges";
+ private static String ROLE_CUSTOMER = "Have Customer User privileges";
+
+ @Test
+ public void oauthGrantAcceptTest() {
+ oauth.clientId("third-party");
+ oauth.doLoginGrant("test-user@localhost", "password");
+
+ grantPage.assertCurrent();
+ Assert.assertTrue(driver.getPageSource().contains(ROLE_USER));
+ Assert.assertTrue(driver.getPageSource().contains(ROLE_CUSTOMER));
+
+ grantPage.accept();
+
+ Assert.assertTrue(oauth.getCurrentQuery().containsKey(OAuth2Constants.CODE));
+
+ Event loginEvent = events.expectLogin()
+ .client("third-party")
+ .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED)
+ .assertEvent();
+ String codeId = loginEvent.getDetails().get(Details.CODE_ID);
+ String sessionId = loginEvent.getSessionId();
+
+ OAuthClient.AccessTokenResponse accessToken = oauth.doAccessTokenRequest(oauth.getCurrentQuery().get(OAuth2Constants.CODE), "password");
+
+ String tokenString = accessToken.getAccessToken();
+ Assert.assertNotNull(tokenString);
+ AccessToken token = oauth.verifyToken(tokenString);
+ assertEquals(sessionId, token.getSessionState());
+
+ AccessToken.Access realmAccess = token.getRealmAccess();
+ assertEquals(1, realmAccess.getRoles().size());
+ Assert.assertTrue(realmAccess.isUserInRole("user"));
+
+ Map<String,AccessToken.Access> resourceAccess = token.getResourceAccess();
+ assertEquals(1, resourceAccess.size());
+ assertEquals(1, resourceAccess.get("test-app").getRoles().size());
+ Assert.assertTrue(resourceAccess.get("test-app").isUserInRole("customer-user"));
+
+ events.expectCodeToToken(codeId, loginEvent.getSessionId()).client("third-party").assertEvent();
+
+ accountAppsPage.open();
+ accountAppsPage.revokeGrant("third-party");
+
+ events.expect(EventType.REVOKE_GRANT)
+ .client("account").detail(Details.REVOKED_CLIENT, "third-party").assertEvent();
+ }
+
+ @Test
+ public void oauthGrantCancelTest() {
+ oauth.clientId("third-party");
+ oauth.doLoginGrant("test-user@localhost", "password");
+
+ grantPage.assertCurrent();
+ Assert.assertTrue(driver.getPageSource().contains(ROLE_USER));
+ Assert.assertTrue(driver.getPageSource().contains(ROLE_CUSTOMER));
+
+ grantPage.cancel();
+
+ Assert.assertTrue(oauth.getCurrentQuery().containsKey(OAuth2Constants.ERROR));
+ assertEquals("access_denied", oauth.getCurrentQuery().get(OAuth2Constants.ERROR));
+
+ events.expectLogin()
+ .client("third-party")
+ .error("rejected_by_user")
+ .removeDetail(Details.CONSENT)
+ .assertEvent();
+ }
+
+ @Test
+ public void oauthGrantNotShownWhenAlreadyGranted() {
+ // Grant permissions on grant screen
+ oauth.clientId("third-party");
+ oauth.doLoginGrant("test-user@localhost", "password");
+
+ grantPage.assertCurrent();
+ grantPage.accept();
+
+ events.expectLogin()
+ .client("third-party")
+ .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED)
+ .assertEvent();
+
+ // Assert permissions granted on Account mgmt. applications page
+ accountAppsPage.open();
+ AccountApplicationsPage.AppEntry thirdPartyEntry = accountAppsPage.getApplications().get("third-party");
+ Assert.assertTrue(thirdPartyEntry.getRolesGranted().contains(ROLE_USER));
+ Assert.assertTrue(thirdPartyEntry.getRolesGranted().contains("Have Customer User privileges in test-app"));
+ Assert.assertTrue(thirdPartyEntry.getProtocolMappersGranted().contains("Full name"));
+ Assert.assertTrue(thirdPartyEntry.getProtocolMappersGranted().contains("Email"));
+
+ // Open login form and assert grantPage not shown
+ oauth.openLoginForm();
+ appPage.assertCurrent();
+ events.expectLogin()
+ .detail(Details.AUTH_METHOD, "sso")
+ .detail(Details.CONSENT, Details.CONSENT_VALUE_PERSISTED_CONSENT)
+ .removeDetail(Details.USERNAME)
+ .client("third-party").assertEvent();
+
+ // Revoke grant in account mgmt.
+ accountAppsPage.open();
+ accountAppsPage.revokeGrant("third-party");
+
+ events.expect(EventType.REVOKE_GRANT)
+ .client("account").detail(Details.REVOKED_CLIENT, "third-party").assertEvent();
+
+ // Open login form again and assert grant Page is shown
+ oauth.openLoginForm();
+ grantPage.assertCurrent();
+ Assert.assertTrue(driver.getPageSource().contains(ROLE_USER));
+ Assert.assertTrue(driver.getPageSource().contains(ROLE_CUSTOMER));
+ }
+
+ @Test
+ public void oauthGrantAddAnotherRoleAndMapper() {
+ // Grant permissions on grant screen
+ oauth.clientId("third-party");
+ oauth.doLoginGrant("test-user@localhost", "password");
+
+ // Add new protocolMapper and role before showing grant page
+ keycloakRule.update(new KeycloakRule.KeycloakSetup() {
+
+ @Override
+ public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+ ProtocolMapperModel protocolMapper = UserSessionNoteMapper.createClaimMapper(KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME,
+ KerberosConstants.GSS_DELEGATION_CREDENTIAL,
+ KerberosConstants.GSS_DELEGATION_CREDENTIAL, "String",
+ true, KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME,
+ true, false);
+
+ ClientModel thirdPartyApp = appRealm.getClientByClientId("third-party");
+ thirdPartyApp.addProtocolMapper(protocolMapper);
+
+ RoleModel newRole = appRealm.addRole("new-role");
+ thirdPartyApp.addScopeMapping(newRole);
+ UserModel testUser = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
+ testUser.grantRole(newRole);
+ }
+
+ });
+
+ // Confirm grant page
+ grantPage.assertCurrent();
+ grantPage.accept();
+ events.expectLogin()
+ .client("third-party")
+ .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED)
+ .assertEvent();
+
+ // Assert new role and protocol mapper not in account mgmt.
+ accountAppsPage.open();
+ AccountApplicationsPage.AppEntry appEntry = accountAppsPage.getApplications().get("third-party");
+ Assert.assertFalse(appEntry.getRolesGranted().contains("new-role"));
+ Assert.assertFalse(appEntry.getProtocolMappersGranted().contains(KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME));
+
+ // Show grant page another time. Just new role and protocol mapper are on the page
+ oauth.openLoginForm();
+ grantPage.assertCurrent();
+ Assert.assertFalse(driver.getPageSource().contains(ROLE_USER));
+ Assert.assertFalse(driver.getPageSource().contains("Full name"));
+ Assert.assertTrue(driver.getPageSource().contains("new-role"));
+ Assert.assertTrue(driver.getPageSource().contains(KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME));
+ grantPage.accept();
+ events.expectLogin()
+ .client("third-party")
+ .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED)
+ .assertEvent();
+
+ // Go to account mgmt. Everything is granted now
+ accountAppsPage.open();
+ appEntry = accountAppsPage.getApplications().get("third-party");
+ Assert.assertTrue(appEntry.getRolesGranted().contains("new-role"));
+ Assert.assertTrue(appEntry.getProtocolMappersGranted().contains(KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME));
+
+ // Revoke
+ accountAppsPage.revokeGrant("third-party");
+ events.expect(EventType.REVOKE_GRANT)
+ .client("account").detail(Details.REVOKED_CLIENT, "third-party").assertEvent();
+
+ // Cleanup
+ keycloakRule.update(new KeycloakRule.KeycloakSetup() {
+
+ @Override
+ public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+ ClientModel thirdPartyApp = appRealm.getClientByClientId("third-party");
+ ProtocolMapperModel gssMapper = thirdPartyApp.getProtocolMapperByName(OIDCLoginProtocol.LOGIN_PROTOCOL, KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME);
+ thirdPartyApp.removeProtocolMapper(gssMapper);
+
+ RoleModel newRole = appRealm.getRole("new-role");
+ appRealm.removeRole(newRole);
+ }
+
+ });
+ }
+
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/ResourceOwnerPasswordCredentialsGrantTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/ResourceOwnerPasswordCredentialsGrantTest.java
index cadeb9e..23d2e5e 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/ResourceOwnerPasswordCredentialsGrantTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/ResourceOwnerPasswordCredentialsGrantTest.java
@@ -1,6 +1,10 @@
package org.keycloak.testsuite.oauth;
import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.DefaultHttpClient;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
@@ -89,6 +93,7 @@ public class ResourceOwnerPasswordCredentialsGrantTest {
.detail(Details.USERNAME, login)
.removeDetail(Details.CODE_ID)
.removeDetail(Details.REDIRECT_URI)
+ .removeDetail(Details.CONSENT)
.assertEvent();
assertEquals(accessToken.getSessionState(), refreshToken.getSessionState());
@@ -124,6 +129,7 @@ public class ResourceOwnerPasswordCredentialsGrantTest {
.detail(Details.REFRESH_TOKEN_ID, refreshToken.getId())
.removeDetail(Details.CODE_ID)
.removeDetail(Details.REDIRECT_URI)
+ .removeDetail(Details.CONSENT)
.assertEvent();
HttpResponse logoutResponse = oauth.doLogout(response.getRefreshToken(), "secret");
@@ -176,6 +182,7 @@ public class ResourceOwnerPasswordCredentialsGrantTest {
.detail(Details.RESPONSE_TYPE, "token")
.removeDetail(Details.CODE_ID)
.removeDetail(Details.REDIRECT_URI)
+ .removeDetail(Details.CONSENT)
.error(Errors.INVALID_USER_CREDENTIALS)
.assertEvent();
}
@@ -199,8 +206,27 @@ public class ResourceOwnerPasswordCredentialsGrantTest {
.detail(Details.USERNAME, "invalid")
.removeDetail(Details.CODE_ID)
.removeDetail(Details.REDIRECT_URI)
+ .removeDetail(Details.CONSENT)
.error(Errors.INVALID_USER_CREDENTIALS)
.assertEvent();
}
+ @Test
+ public void grantAccessTokenMissingGrantType() throws Exception {
+ oauth.clientId("resource-owner");
+
+ DefaultHttpClient client = new DefaultHttpClient();
+ try {
+ HttpPost post = new HttpPost(oauth.getResourceOwnerPasswordCredentialGrantUrl());
+ OAuthClient.AccessTokenResponse response = new OAuthClient.AccessTokenResponse(client.execute(post));
+
+ assertEquals(400, response.getStatusCode());
+
+ assertEquals("invalid_request", response.getError());
+ assertEquals("Missing form parameter: grant_type", response.getErrorDescription());
+ } finally {
+ client.close();
+ }
+ }
+
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java
index 4e4f57a..2ad8e1b 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java
@@ -28,6 +28,7 @@ import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
+import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONObject;
@@ -113,143 +114,164 @@ public class OAuthClient {
}
public AccessTokenResponse doAccessTokenRequest(String code, String password) {
- HttpClient client = new DefaultHttpClient();
- HttpPost post = new HttpPost(getAccessTokenUrl());
+ CloseableHttpClient client = new DefaultHttpClient();
+ try {
+ HttpPost post = new HttpPost(getAccessTokenUrl());
- List<NameValuePair> parameters = new LinkedList<NameValuePair>();
- parameters.add(new BasicNameValuePair(OAuth2Constants.GRANT_TYPE, OAuth2Constants.AUTHORIZATION_CODE));
+ List<NameValuePair> parameters = new LinkedList<NameValuePair>();
+ parameters.add(new BasicNameValuePair(OAuth2Constants.GRANT_TYPE, OAuth2Constants.AUTHORIZATION_CODE));
- if (code != null) {
- parameters.add(new BasicNameValuePair(OAuth2Constants.CODE, code));
- }
- if (redirectUri != null) {
- parameters.add(new BasicNameValuePair(OAuth2Constants.REDIRECT_URI, redirectUri));
- }
- if (clientId != null && password != null) {
- String authorization = BasicAuthHelper.createHeader(clientId, password);
- post.setHeader("Authorization", authorization);
- }
- else if (clientId != null) {
- parameters.add(new BasicNameValuePair(OAuth2Constants.CLIENT_ID, clientId));
- }
+ if (code != null) {
+ parameters.add(new BasicNameValuePair(OAuth2Constants.CODE, code));
+ }
+ if (redirectUri != null) {
+ parameters.add(new BasicNameValuePair(OAuth2Constants.REDIRECT_URI, redirectUri));
+ }
+ if (clientId != null && password != null) {
+ String authorization = BasicAuthHelper.createHeader(clientId, password);
+ post.setHeader("Authorization", authorization);
+ } else if (clientId != null) {
+ parameters.add(new BasicNameValuePair(OAuth2Constants.CLIENT_ID, clientId));
+ }
- if(clientSessionState != null) {
- parameters.add(new BasicNameValuePair(AdapterConstants.CLIENT_SESSION_STATE, clientSessionState));
- }
+ if (clientSessionState != null) {
+ parameters.add(new BasicNameValuePair(AdapterConstants.CLIENT_SESSION_STATE, clientSessionState));
+ }
- if(clientSessionHost != null) {
- parameters.add(new BasicNameValuePair(AdapterConstants.CLIENT_SESSION_HOST, clientSessionHost));
- }
+ if (clientSessionHost != null) {
+ parameters.add(new BasicNameValuePair(AdapterConstants.CLIENT_SESSION_HOST, clientSessionHost));
+ }
- UrlEncodedFormEntity formEntity = null;
- try {
- formEntity = new UrlEncodedFormEntity(parameters, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException(e);
- }
- post.setEntity(formEntity);
+ UrlEncodedFormEntity formEntity = null;
+ try {
+ formEntity = new UrlEncodedFormEntity(parameters, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ post.setEntity(formEntity);
- try {
- return new AccessTokenResponse(client.execute(post));
- } catch (Exception e) {
- throw new RuntimeException("Failed to retrieve access token", e);
+ try {
+ return new AccessTokenResponse(client.execute(post));
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to retrieve access token", e);
+ }
+ } finally {
+ closeClient(client);
}
}
public AccessTokenResponse doGrantAccessTokenRequest(String clientSecret, String username, String password) throws Exception {
- HttpClient client = new DefaultHttpClient();
- HttpPost post = new HttpPost(getResourceOwnerPasswordCredentialGrantUrl());
+ CloseableHttpClient client = new DefaultHttpClient();
+ try {
+ HttpPost post = new HttpPost(getResourceOwnerPasswordCredentialGrantUrl());
- String authorization = BasicAuthHelper.createHeader(clientId, clientSecret);
- post.setHeader("Authorization", authorization);
+ String authorization = BasicAuthHelper.createHeader(clientId, clientSecret);
+ post.setHeader("Authorization", authorization);
- List<NameValuePair> parameters = new LinkedList<NameValuePair>();
- parameters.add(new BasicNameValuePair(OAuth2Constants.GRANT_TYPE, OAuth2Constants.PASSWORD));
- parameters.add(new BasicNameValuePair("username", username));
- parameters.add(new BasicNameValuePair("password", password));
+ List<NameValuePair> parameters = new LinkedList<NameValuePair>();
+ parameters.add(new BasicNameValuePair(OAuth2Constants.GRANT_TYPE, OAuth2Constants.PASSWORD));
+ parameters.add(new BasicNameValuePair("username", username));
+ parameters.add(new BasicNameValuePair("password", password));
- if(clientSessionState != null) {
- parameters.add(new BasicNameValuePair(AdapterConstants.CLIENT_SESSION_STATE, clientSessionState));
- }
- if(clientSessionHost != null) {
- parameters.add(new BasicNameValuePair(AdapterConstants.CLIENT_SESSION_HOST, clientSessionHost));
- }
+ if (clientSessionState != null) {
+ parameters.add(new BasicNameValuePair(AdapterConstants.CLIENT_SESSION_STATE, clientSessionState));
+ }
+ if (clientSessionHost != null) {
+ parameters.add(new BasicNameValuePair(AdapterConstants.CLIENT_SESSION_HOST, clientSessionHost));
+ }
- UrlEncodedFormEntity formEntity;
- try {
- formEntity = new UrlEncodedFormEntity(parameters, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException(e);
- }
- post.setEntity(formEntity);
+ UrlEncodedFormEntity formEntity;
+ try {
+ formEntity = new UrlEncodedFormEntity(parameters, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ post.setEntity(formEntity);
- return new AccessTokenResponse(client.execute(post));
+ return new AccessTokenResponse(client.execute(post));
+ } finally {
+ closeClient(client);
+ }
}
public HttpResponse doLogout(String refreshToken, String clientSecret) throws IOException {
- HttpClient client = new DefaultHttpClient();
- HttpPost post = new HttpPost(getLogoutUrl(null, null));
+ CloseableHttpClient client = new DefaultHttpClient();
+ try {
+ HttpPost post = new HttpPost(getLogoutUrl(null, null));
- List<NameValuePair> parameters = new LinkedList<NameValuePair>();
- if (refreshToken != null) {
- parameters.add(new BasicNameValuePair(OAuth2Constants.REFRESH_TOKEN, refreshToken));
- }
- if (clientId != null && clientSecret != null) {
- String authorization = BasicAuthHelper.createHeader(clientId, clientSecret);
- post.setHeader("Authorization", authorization);
- }
- else if (clientId != null) {
- parameters.add(new BasicNameValuePair(OAuth2Constants.CLIENT_ID, clientId));
- }
+ List<NameValuePair> parameters = new LinkedList<NameValuePair>();
+ if (refreshToken != null) {
+ parameters.add(new BasicNameValuePair(OAuth2Constants.REFRESH_TOKEN, refreshToken));
+ }
+ if (clientId != null && clientSecret != null) {
+ String authorization = BasicAuthHelper.createHeader(clientId, clientSecret);
+ post.setHeader("Authorization", authorization);
+ } else if (clientId != null) {
+ parameters.add(new BasicNameValuePair(OAuth2Constants.CLIENT_ID, clientId));
+ }
- UrlEncodedFormEntity formEntity;
- try {
- formEntity = new UrlEncodedFormEntity(parameters, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException(e);
- }
- post.setEntity(formEntity);
+ UrlEncodedFormEntity formEntity;
+ try {
+ formEntity = new UrlEncodedFormEntity(parameters, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ post.setEntity(formEntity);
- return client.execute(post);
+ return client.execute(post);
+ } finally {
+ closeClient(client);
+ }
}
public AccessTokenResponse doRefreshTokenRequest(String refreshToken, String password) {
- HttpClient client = new DefaultHttpClient();
- HttpPost post = new HttpPost(getRefreshTokenUrl());
+ CloseableHttpClient client = new DefaultHttpClient();
+ try {
+ HttpPost post = new HttpPost(getRefreshTokenUrl());
- List<NameValuePair> parameters = new LinkedList<NameValuePair>();
- parameters.add(new BasicNameValuePair(OAuth2Constants.GRANT_TYPE, OAuth2Constants.REFRESH_TOKEN));
+ List<NameValuePair> parameters = new LinkedList<NameValuePair>();
+ parameters.add(new BasicNameValuePair(OAuth2Constants.GRANT_TYPE, OAuth2Constants.REFRESH_TOKEN));
- if (refreshToken != null) {
- parameters.add(new BasicNameValuePair(OAuth2Constants.REFRESH_TOKEN, refreshToken));
- }
- if (clientId != null && password != null) {
- String authorization = BasicAuthHelper.createHeader(clientId, password);
- post.setHeader("Authorization", authorization);
- }
- else if (clientId != null) {
- parameters.add(new BasicNameValuePair(OAuth2Constants.CLIENT_ID, clientId));
- }
+ if (refreshToken != null) {
+ parameters.add(new BasicNameValuePair(OAuth2Constants.REFRESH_TOKEN, refreshToken));
+ }
+ if (clientId != null && password != null) {
+ String authorization = BasicAuthHelper.createHeader(clientId, password);
+ post.setHeader("Authorization", authorization);
+ } else if (clientId != null) {
+ parameters.add(new BasicNameValuePair(OAuth2Constants.CLIENT_ID, clientId));
+ }
- if(clientSessionState != null) {
- parameters.add(new BasicNameValuePair(AdapterConstants.CLIENT_SESSION_STATE, clientSessionState));
- }
- if(clientSessionHost != null) {
- parameters.add(new BasicNameValuePair(AdapterConstants.CLIENT_SESSION_HOST, clientSessionHost));
- }
+ if (clientSessionState != null) {
+ parameters.add(new BasicNameValuePair(AdapterConstants.CLIENT_SESSION_STATE, clientSessionState));
+ }
+ if (clientSessionHost != null) {
+ parameters.add(new BasicNameValuePair(AdapterConstants.CLIENT_SESSION_HOST, clientSessionHost));
+ }
- UrlEncodedFormEntity formEntity;
- try {
- formEntity = new UrlEncodedFormEntity(parameters, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException(e);
+ UrlEncodedFormEntity formEntity;
+ try {
+ formEntity = new UrlEncodedFormEntity(parameters, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ post.setEntity(formEntity);
+
+ try {
+ return new AccessTokenResponse(client.execute(post));
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to retrieve access token", e);
+ }
+ } finally {
+ closeClient(client);
}
- post.setEntity(formEntity);
+ }
+ private void closeClient(CloseableHttpClient client) {
try {
- return new AccessTokenResponse(client.execute(post));
- } catch (Exception e) {
- throw new RuntimeException("Failed to retrieve access token", e);
+ client.close();
+ } catch (IOException ioe) {
+ throw new RuntimeException(ioe);
}
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/offlineconfig/AdminRecoveryTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/offlineconfig/AdminRecoveryTest.java
new file mode 100644
index 0000000..506a154
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/offlineconfig/AdminRecoveryTest.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2015 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.keycloak.testsuite.offlineconfig;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserCredentialModel;
+import org.keycloak.models.UserCredentialValueModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.UserModel.RequiredAction;
+import org.keycloak.offlineconfig.AdminRecovery;
+import org.keycloak.offlineconfig.OfflineConfigException;
+import org.keycloak.services.managers.RealmManager;
+import org.keycloak.testsuite.rule.KeycloakRule;
+import org.keycloak.testsuite.rule.WebRule;
+
+/**
+ * Test the AdminRecovery class.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2015 Red Hat Inc.
+ */
+public class AdminRecoveryTest {
+ @ClassRule
+ public static KeycloakRule keycloakRule = new KeycloakRule() {
+
+ @Override
+ protected void after() {
+
+ // Need to reset admin user to default password and remove required action to not break next tests
+ update(new KeycloakSetup() {
+
+ @Override
+ public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+ UserModel adminUser = session.users().getUserByUsername("admin", adminstrationRealm);
+ UserCredentialModel password = UserCredentialModel.password("admin");
+ adminUser.updateCredential(password);
+
+ adminUser.removeRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
+ }
+ });
+
+ super.after();
+ }
+ };
+
+ @Rule
+ public WebRule webRule = new WebRule(this);
+
+ // Verifies that system properties were cleared at the end of recovery
+ @After
+ public void verifySysPropsCleared() {
+ Assert.assertNull(System.getProperty(AdminRecovery.RECOVER_ADMIN_ACCOUNT));
+ Assert.assertNull(System.getProperty(AdminRecovery.TEMP_ADMIN_PASSWORD));
+ }
+
+ @Test
+ public void testAdminDeletedRecovery() {
+ KeycloakSession session = keycloakRule.startSession();
+ RealmModel masterRealm = session.realms().getRealmByName("master");
+ UserModel adminUser = session.users().getUserByUsername("admin", masterRealm);
+ session.users().removeUser(masterRealm, adminUser);
+ adminUser = session.users().getUserByUsername("admin", masterRealm);
+ keycloakRule.stopSession(session, true);
+
+ Assert.assertNull(adminUser);
+
+ doAdminRecovery(session);
+
+ session = keycloakRule.startSession();
+ adminUser = session.users().getUserByUsername("admin", masterRealm);
+ Assert.assertNotNull(adminUser);
+ Assert.assertTrue(adminUser.getRequiredActions().contains(RequiredAction.UPDATE_PASSWORD.toString()));
+ }
+
+ @Test
+ public void testAdminPasswordRecovery() {
+ KeycloakSession session = keycloakRule.startSession();
+ RealmModel masterRealm = session.realms().getRealmByName("master");
+ UserModel adminUser = session.users().getUserByUsername("admin", masterRealm);
+ UserCredentialValueModel password = adminUser.getCredentialsDirectly().get(0);
+ password.setValue("forgotten-password");
+ adminUser.updateCredentialDirectly(password);
+ keycloakRule.stopSession(session, true);
+
+ Assert.assertEquals("forgotten-password", getAdminPassword());
+
+ doAdminRecovery(session);
+
+ Assert.assertNotEquals("forgotten-password", getAdminPassword());
+ }
+
+ @Test(expected = OfflineConfigException.class)
+ public void testAdminRecoveryWithoutPassword() {
+ KeycloakSession session = keycloakRule.startSession();
+ System.setProperty(AdminRecovery.RECOVER_ADMIN_ACCOUNT, "true");
+ AdminRecovery.recover(session.getKeycloakSessionFactory());
+ }
+
+ private void doAdminRecovery(KeycloakSession session) {
+ System.setProperty(AdminRecovery.RECOVER_ADMIN_ACCOUNT, "true");
+ System.setProperty(AdminRecovery.TEMP_ADMIN_PASSWORD, "foo");
+ AdminRecovery.recover(session.getKeycloakSessionFactory());
+ }
+
+ private String getAdminPassword() {
+ KeycloakSession session = keycloakRule.startSession();
+ RealmModel masterRealm = session.realms().getRealmByName("master");
+ UserModel adminUser = session.users().getUserByUsername("admin", masterRealm);
+ UserCredentialValueModel password = adminUser.getCredentialsDirectly().get(0);
+ keycloakRule.stopSession(session, true);
+ return password.getValue();
+ }
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/RegisterPage.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/RegisterPage.java
index 28c3796..5904da1 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/RegisterPage.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/RegisterPage.java
@@ -57,25 +57,6 @@ public class RegisterPage extends AbstractPage {
@FindBy(className = "feedback-error")
private WebElement loginErrorMessage;
- public void register(String firstName, String lastName, String email, String username, String password, String passwordConfirm,
- String street, String cityOrLocality, String stateOrRegion, String zipOrPostalCode, String country) {
- fillExtendedField("street", street);
- fillExtendedField("locality", cityOrLocality);
- fillExtendedField("region", stateOrRegion);
- fillExtendedField("postal_code", zipOrPostalCode);
- fillExtendedField("country", country);
-
- register(firstName, lastName, email, username, password, passwordConfirm);
- }
-
- private void fillExtendedField(String fieldName, String value) {
- WebElement field = driver.findElement(By.id("user.attributes." + fieldName));
- field.clear();
- if (value != null) {
- field.sendKeys(value);
- }
- }
-
public void register(String firstName, String lastName, String email, String username, String password, String passwordConfirm) {
firstNameInput.clear();
if (firstName != null) {
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java
index 5470041..e82b04a 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java
@@ -1,473 +1,495 @@
-package org.keycloak.testsuite.saml;
-
-import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataOutput;
-import org.junit.Assert;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.keycloak.Config;
-import org.keycloak.models.ClientModel;
-import org.keycloak.models.ClientSessionModel;
-import org.keycloak.models.Constants;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.ProtocolMapperModel;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.models.UserSessionModel;
-import org.keycloak.protocol.oidc.OIDCLoginProtocol;
-import org.keycloak.protocol.oidc.TokenManager;
-import org.keycloak.protocol.saml.mappers.AttributeStatementHelper;
-import org.keycloak.protocol.saml.mappers.HardcodedAttributeMapper;
-import org.keycloak.protocol.saml.mappers.HardcodedRole;
-import org.keycloak.protocol.saml.mappers.RoleListMapper;
-import org.keycloak.protocol.saml.mappers.RoleNameMapper;
-import org.keycloak.representations.AccessToken;
-import org.keycloak.services.managers.RealmManager;
-import org.keycloak.services.resources.admin.AdminRoot;
-import org.keycloak.testsuite.pages.LoginPage;
-import org.keycloak.testsuite.rule.KeycloakRule;
-import org.keycloak.testsuite.rule.WebResource;
-import org.keycloak.testsuite.rule.WebRule;
-import org.openqa.selenium.WebDriver;
-import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
-import org.keycloak.saml.processing.api.saml.v2.response.SAML2Response;
-import org.keycloak.saml.processing.core.saml.v2.constants.X500SAMLProfileConstants;
-import org.keycloak.dom.saml.v2.assertion.AssertionType;
-import org.keycloak.dom.saml.v2.assertion.AttributeStatementType;
-import org.keycloak.dom.saml.v2.assertion.AttributeType;
-import org.keycloak.dom.saml.v2.protocol.ResponseType;
-import org.keycloak.saml.processing.web.util.PostBindingUtil;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.ws.rs.client.Client;
-import javax.ws.rs.client.ClientBuilder;
-import javax.ws.rs.client.ClientRequestContext;
-import javax.ws.rs.client.ClientRequestFilter;
-import javax.ws.rs.client.Entity;
-import javax.ws.rs.client.WebTarget;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriBuilder;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
- * @version $Revision: 1 $
- */
-public class SamlBindingTest {
-
- @ClassRule
- public static SamlKeycloakRule keycloakRule = new SamlKeycloakRule() {
- @Override
- public void initWars() {
- ClassLoader classLoader = SamlBindingTest.class.getClassLoader();
-
- initializeSamlSecuredWar("/saml/simple-post", "/sales-post", "post.war", classLoader);
- initializeSamlSecuredWar("/saml/signed-post", "/sales-post-sig", "post-sig.war", classLoader);
- initializeSamlSecuredWar("/saml/signed-post-email", "/sales-post-sig-email", "post-sig-email.war", classLoader);
- initializeSamlSecuredWar("/saml/signed-post-transient", "/sales-post-sig-transient", "post-sig-transient.war", classLoader);
- initializeSamlSecuredWar("/saml/signed-post-persistent", "/sales-post-sig-persistent", "post-sig-persistent.war", classLoader);
- initializeSamlSecuredWar("/saml/signed-metadata", "/sales-metadata", "post-metadata.war", classLoader);
- initializeSamlSecuredWar("/saml/signed-get", "/employee-sig", "employee-sig.war", classLoader);
- //initializeSamlSecuredWar("/saml/simple-get", "/employee", "employee.war", classLoader);
- initializeSamlSecuredWar("/saml/signed-front-get", "/employee-sig-front", "employee-sig-front.war", classLoader);
- initializeSamlSecuredWar("/saml/bad-client-signed-post", "/bad-client-sales-post-sig", "bad-client-post-sig.war", classLoader);
- initializeSamlSecuredWar("/saml/bad-realm-signed-post", "/bad-realm-sales-post-sig", "bad-realm-post-sig.war", classLoader);
- initializeSamlSecuredWar("/saml/encrypted-post", "/sales-post-enc", "post-enc.war", classLoader);
- uploadSP();
- server.getServer().deploy(createDeploymentInfo("employee.war", "/employee", SamlSPFacade.class));
-
-
-
- }
-
- @Override
- public String getRealmJson() {
- return "/saml/testsaml.json";
- }
- };
-
- public static class SamlSPFacade extends HttpServlet {
- public static String samlResponse;
-
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- handler(req, resp);
- }
-
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- handler(req, resp);
- }
-
- private void handler(HttpServletRequest req, HttpServletResponse resp) {
- System.out.println("********* HERE ******");
- if (req.getParameterMap().isEmpty()) {
- System.out.println("redirecting");
- resp.setStatus(302);
- resp.setHeader("Location", "http://localhost:8081/auth/realms/demo/protocol/saml?SAMLRequest=jVJbT8IwFP4rS99HuwluNIwEIUYSLwugD76Y2h2kSdfOng7l31uGRn0ATfrQ9HznfJfTEYpaN3zS%2Bo1ZwGsL6KP3WhvkXaEgrTPcClTIjagBuZd8Obm55mmP8cZZb6XV5NByGiwQwXllDYkmX9epNdjW4JbgtkrC%2FeK6IBvvG06ptlLojUXPc5YnFOpG2x0AJdEsaFRG7PuPoUWwQx0IXSOtoLb0SynduyLRpXUSOs8FWQuNQKL5rCDz2VO%2FymEgIY2zlJ3H%2FSx9jkU%2BzOK0ys8yNmSSsUEAYxnsqC18tyO2MDfohfEFSVkyiNlZzM5XacrDSbJePug%2Fkqj8FHKhTKXMy%2BnIng8g5FerVRmXd8sViR7AYec8AMh4tPfDO3L3Y2%2F%2F3cT4j7BH9Mf8A1nDb8PA%2Bay0WsldNNHavk1D1D5k4V0LXbi18MclJL2ke1FVvO6gvDXYgFRrBRWh4wPp7z85%2FgA%3D");
- return;
- }
- System.out.println("received response");
- samlResponse = req.getParameter("SAMLResponse");
- }
- }
-
- @Rule
- public WebRule webRule = new WebRule(this);
- @WebResource
- protected WebDriver driver;
- @WebResource
- protected LoginPage loginPage;
-
- protected void checkLoggedOut(String mainUrl) {
- String pageSource = driver.getPageSource();
- System.out.println("*** logout pagesouce ***");
- System.out.println(pageSource);
- System.out.println("driver url: " + driver.getCurrentUrl());
- Assert.assertTrue(pageSource.contains("request-path: /logout.jsp"));
- driver.navigate().to(mainUrl);
- Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
- }
-
-
- @Test
- public void testPostSimpleLoginLogout() {
- driver.navigate().to("http://localhost:8081/sales-post/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post/");
- System.out.println(driver.getPageSource());
- Assert.assertTrue(driver.getPageSource().contains("bburke"));
- driver.navigate().to("http://localhost:8081/sales-post?GLO=true");
- checkLoggedOut("http://localhost:8081/sales-post/");
- }
- @Test
- public void testPostSignedLoginLogout() {
- driver.navigate().to("http://localhost:8081/sales-post-sig/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig/");
- Assert.assertTrue(driver.getPageSource().contains("bburke"));
- driver.navigate().to("http://localhost:8081/sales-post-sig?GLO=true");
- checkLoggedOut("http://localhost:8081/sales-post-sig/");
-
- }
- @Test
- public void testPostSignedLoginLogoutTransientNameID() {
- driver.navigate().to("http://localhost:8081/sales-post-sig-transient/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig-transient/");
- System.out.println(driver.getPageSource());
- Assert.assertFalse(driver.getPageSource().contains("bburke"));
- Assert.assertTrue(driver.getPageSource().contains("principal=G-"));
- driver.navigate().to("http://localhost:8081/sales-post-sig-transient?GLO=true");
- checkLoggedOut("http://localhost:8081/sales-post-sig-transient/");
-
- }
- @Test
- public void testPostSignedLoginLogoutPersistentNameID() {
- driver.navigate().to("http://localhost:8081/sales-post-sig-persistent/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig-persistent/");
- System.out.println(driver.getPageSource());
- Assert.assertFalse(driver.getPageSource().contains("bburke"));
- Assert.assertTrue(driver.getPageSource().contains("principal=G-"));
- driver.navigate().to("http://localhost:8081/sales-post-sig-persistent?GLO=true");
- checkLoggedOut("http://localhost:8081/sales-post-sig-persistent/");
-
- }
- @Test
- public void testPostSignedLoginLogoutEmailNameID() {
- driver.navigate().to("http://localhost:8081/sales-post-sig-email/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig-email/");
- System.out.println(driver.getPageSource());
- Assert.assertTrue(driver.getPageSource().contains("principal=bburke@redhat.com"));
- driver.navigate().to("http://localhost:8081/sales-post-sig-email?GLO=true");
- checkLoggedOut("http://localhost:8081/sales-post-sig-email/");
-
- }
-
-
- @Test
- public void testAttributes() throws Exception {
- // this test has a hardcoded SAMLRequest and we hack a SP face servlet to get the SAMLResponse so we can look
- // at the assertions sent. This is because Picketlink, AFAICT, does not give you any way to get access to
- // the assertion.
-
- {
- SamlSPFacade.samlResponse = null;
- driver.navigate().to("http://localhost:8081/employee/");
- Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
- System.out.println(driver.getCurrentUrl());
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee/");
- Assert.assertNotNull(SamlSPFacade.samlResponse);
- SAML2Response saml2Response = new SAML2Response();
- byte[] samlResponse = PostBindingUtil.base64Decode(SamlSPFacade.samlResponse);
- ResponseType rt = saml2Response.getResponseType(new ByteArrayInputStream(samlResponse));
- Assert.assertTrue(rt.getAssertions().size() == 1);
- AssertionType assertion = rt.getAssertions().get(0).getAssertion();
-
- // test attributes and roles
-
- boolean email = false;
- boolean phone = false;
- boolean userRole = false;
- boolean managerRole = false;
- for (AttributeStatementType statement : assertion.getAttributeStatements()) {
- for (AttributeStatementType.ASTChoiceType choice : statement.getAttributes()) {
- AttributeType attr = choice.getAttribute();
- if (X500SAMLProfileConstants.EMAIL.getFriendlyName().equals(attr.getFriendlyName())) {
- Assert.assertEquals(X500SAMLProfileConstants.EMAIL.get(), attr.getName());
- Assert.assertEquals(JBossSAMLURIConstants.ATTRIBUTE_FORMAT_URI.get(), attr.getNameFormat());
- Assert.assertEquals(attr.getAttributeValue().get(0), "bburke@redhat.com");
- email = true;
- } else if (attr.getName().equals("phone")) {
- Assert.assertEquals(JBossSAMLURIConstants.ATTRIBUTE_FORMAT_BASIC.get(), attr.getNameFormat());
- Assert.assertEquals(attr.getAttributeValue().get(0), "617");
- phone = true;
- } else if (attr.getName().equals("Role")) {
- if (attr.getAttributeValue().get(0).equals("manager")) managerRole = true;
- if (attr.getAttributeValue().get(0).equals("user")) userRole = true;
- }
- }
-
- }
-
- Assert.assertTrue(email);
- Assert.assertTrue(phone);
- Assert.assertTrue(userRole);
- Assert.assertTrue(managerRole);
- }
-
- keycloakRule.update(new KeycloakRule.KeycloakSetup() {
- @Override
- public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- ClientModel app = appRealm.getClientByClientId("http://localhost:8081/employee/");
- for (ProtocolMapperModel mapper : app.getProtocolMappers()) {
- if (mapper.getName().equals("role-list")) {
- app.removeProtocolMapper(mapper);
- mapper.setId(null);
- mapper.getConfig().put(RoleListMapper.SINGLE_ROLE_ATTRIBUTE, "true");
- mapper.getConfig().put(AttributeStatementHelper.SAML_ATTRIBUTE_NAME, "memberOf");
- app.addProtocolMapper(mapper);
- }
- }
- app.addProtocolMapper(HardcodedAttributeMapper.create("hardcoded-attribute", "hardcoded-attribute", "Basic", null, "hard", false, null));
- app.addProtocolMapper(HardcodedRole.create("hardcoded-role", "hardcoded-role"));
- app.addProtocolMapper(RoleNameMapper.create("renamed-role", "manager", "el-jefe"));
- app.addProtocolMapper(RoleNameMapper.create("renamed-employee-role", "http://localhost:8081/employee/.employee", "pee-on"));
- }
- }, "demo");
-
- System.out.println(">>>>>>>>>> single role attribute <<<<<<<<");
-
- {
- SamlSPFacade.samlResponse = null;
- driver.navigate().to("http://localhost:8081/employee/");
- System.out.println(driver.getCurrentUrl());
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee/");
- Assert.assertNotNull(SamlSPFacade.samlResponse);
- SAML2Response saml2Response = new SAML2Response();
- byte[] samlResponse = PostBindingUtil.base64Decode(SamlSPFacade.samlResponse);
- ResponseType rt = saml2Response.getResponseType(new ByteArrayInputStream(samlResponse));
- Assert.assertTrue(rt.getAssertions().size() == 1);
- AssertionType assertion = rt.getAssertions().get(0).getAssertion();
-
- // test attributes and roles
-
- boolean userRole = false;
- boolean managerRole = false;
- boolean single = false;
- boolean hardcodedRole = false;
- boolean hardcodedAttribute = false;
- boolean peeOn = false;
- for (AttributeStatementType statement : assertion.getAttributeStatements()) {
- for (AttributeStatementType.ASTChoiceType choice : statement.getAttributes()) {
- AttributeType attr = choice.getAttribute();
- if (attr.getName().equals("memberOf")) {
- if (single) Assert.fail("too many role attributes");
- single = true;
- for (Object value : attr.getAttributeValue()) {
- if (value.equals("el-jefe")) managerRole = true;
- if (value.equals("user")) userRole = true;
- if (value.equals("hardcoded-role")) hardcodedRole = true;
- if (value.equals("pee-on")) peeOn = true;
- }
- } else if (attr.getName().equals("hardcoded-attribute")) {
- hardcodedAttribute = true;
- Assert.assertEquals(attr.getAttributeValue().get(0), "hard");
- }
- }
-
- }
-
- Assert.assertTrue(single);
- Assert.assertTrue(hardcodedAttribute);
- Assert.assertTrue(hardcodedRole);
- Assert.assertTrue(peeOn);
- Assert.assertTrue(userRole);
- Assert.assertTrue(managerRole);
- }
- }
-
- @Test
- public void testRedirectSignedLoginLogout() {
- driver.navigate().to("http://localhost:8081/employee-sig/");
- Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee-sig/");
- Assert.assertTrue(driver.getPageSource().contains("bburke"));
- driver.navigate().to("http://localhost:8081/employee-sig?GLO=true");
- checkLoggedOut("http://localhost:8081/employee-sig/");
-
- }
-
- @Test
- public void testRedirectSignedLoginLogoutFrontNoSSO() {
- driver.navigate().to("http://localhost:8081/employee-sig-front/");
- Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee-sig-front/");
- Assert.assertTrue(driver.getPageSource().contains("bburke"));
- driver.navigate().to("http://localhost:8081/employee-sig-front?GLO=true");
- checkLoggedOut("http://localhost:8081/employee-sig-front/");
-
- }
-
- @Test
- public void testRedirectSignedLoginLogoutFront() {
- // visit 1st app an logg in
- System.out.println("visit 1st app ");
- driver.navigate().to("http://localhost:8081/employee-sig/");
- Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
- System.out.println("login to form");
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee-sig/");
- Assert.assertTrue(driver.getPageSource().contains("bburke"));
-
- // visit 2nd app
- System.out.println("visit 2nd app ");
- driver.navigate().to("http://localhost:8081/employee-sig-front/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee-sig-front/");
- Assert.assertTrue(driver.getPageSource().contains("bburke"));
-
- // visit 3rd app
- System.out.println("visit 3rd app ");
- driver.navigate().to("http://localhost:8081/sales-post-sig/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig/");
- Assert.assertTrue(driver.getPageSource().contains("bburke"));
-
- // logout of first app
- System.out.println("GLO");
- driver.navigate().to("http://localhost:8081/employee-sig?GLO=true");
- checkLoggedOut("http://localhost:8081/employee-sig/");
- driver.navigate().to("http://localhost:8081/employee-sig-front/");
- Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
- driver.navigate().to("http://localhost:8081/sales-post-sig/");
- Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
-
- }
-
- @Test
- public void testPostEncryptedLoginLogout() {
- driver.navigate().to("http://localhost:8081/sales-post-enc/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-enc/");
- Assert.assertTrue(driver.getPageSource().contains("bburke"));
- driver.navigate().to("http://localhost:8081/sales-post-enc?GLO=true");
- checkLoggedOut("http://localhost:8081/sales-post-enc/");
-
- }
- @Test
- public void testPostBadClientSignature() {
- driver.navigate().to("http://localhost:8081/bad-client-sales-post-sig/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
- Assert.assertEquals(driver.getTitle(), "We're sorry...");
-
- }
-
- @Test
- public void testPostBadRealmSignature() {
- driver.navigate().to("http://localhost:8081/bad-realm-sales-post-sig/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/bad-realm-sales-post-sig/");
- Assert.assertTrue(driver.getPageSource().contains("null"));
- }
-
- private static String createToken() {
- KeycloakSession session = keycloakRule.startSession();
- try {
- RealmManager manager = new RealmManager(session);
-
- RealmModel adminRealm = manager.getRealm(Config.getAdminRealm());
- ClientModel adminConsole = adminRealm.getClientByClientId(Constants.ADMIN_CONSOLE_CLIENT_ID);
- TokenManager tm = new TokenManager();
- UserModel admin = session.users().getUserByUsername("admin", adminRealm);
- ClientSessionModel clientSession = session.sessions().createClientSession(adminRealm, adminConsole);
- clientSession.setNote(OIDCLoginProtocol.ISSUER, "http://localhost:8081/auth/realms/master");
- UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, "admin", null, "form", false, null, null);
- AccessToken token = tm.createClientAccessToken(session, tm.getAccess(null, adminConsole, admin), adminRealm, adminConsole, admin, userSession, clientSession);
- return tm.encodeToken(adminRealm, token);
- } finally {
- keycloakRule.stopSession(session, true);
- }
- }
-
-
- @Test
- public void testMetadataPostSignedLoginLogout() throws Exception {
-
- driver.navigate().to("http://localhost:8081/sales-metadata/");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
- loginPage.login("bburke", "password");
- Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-metadata/");
- String pageSource = driver.getPageSource();
- Assert.assertTrue(pageSource.contains("bburke"));
- driver.navigate().to("http://localhost:8081/sales-metadata?GLO=true");
- checkLoggedOut("http://localhost:8081/sales-metadata/");
-
- }
-
- public static void uploadSP() {
- String token = createToken();
- final String authHeader = "Bearer " + token;
- ClientRequestFilter authFilter = new ClientRequestFilter() {
- @Override
- public void filter(ClientRequestContext requestContext) throws IOException {
- requestContext.getHeaders().add(HttpHeaders.AUTHORIZATION, authHeader);
- }
- };
- Client client = ClientBuilder.newBuilder().register(authFilter).build();
- UriBuilder authBase = UriBuilder.fromUri("http://localhost:8081/auth");
- WebTarget adminRealms = client.target(AdminRoot.realmsUrl(authBase));
-
-
- MultipartFormDataOutput formData = new MultipartFormDataOutput();
- InputStream is = SamlBindingTest.class.getResourceAsStream("/saml/sp-metadata.xml");
- Assert.assertNotNull(is);
- formData.addFormData("file", is, MediaType.APPLICATION_XML_TYPE);
-
- WebTarget upload = adminRealms.path("demo/client-importers/saml2-entity-descriptor/upload");
- System.out.println(upload.getUri());
- Response response = upload.request().post(Entity.entity(formData, MediaType.MULTIPART_FORM_DATA));
- Assert.assertEquals(204, response.getStatus());
- response.close();
- client.close();
- }
-
-
-}
+package org.keycloak.testsuite.saml;
+
+import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataOutput;
+import org.junit.Assert;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.keycloak.Config;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.ClientSessionModel;
+import org.keycloak.models.Constants;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ProtocolMapperModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.UserSessionModel;
+import org.keycloak.protocol.oidc.OIDCLoginProtocol;
+import org.keycloak.protocol.oidc.TokenManager;
+import org.keycloak.protocol.saml.mappers.AttributeStatementHelper;
+import org.keycloak.protocol.saml.mappers.HardcodedAttributeMapper;
+import org.keycloak.protocol.saml.mappers.HardcodedRole;
+import org.keycloak.protocol.saml.mappers.RoleListMapper;
+import org.keycloak.protocol.saml.mappers.RoleNameMapper;
+import org.keycloak.representations.AccessToken;
+import org.keycloak.services.managers.RealmManager;
+import org.keycloak.services.resources.admin.AdminRoot;
+import org.keycloak.testsuite.pages.LoginPage;
+import org.keycloak.testsuite.rule.KeycloakRule;
+import org.keycloak.testsuite.rule.WebResource;
+import org.keycloak.testsuite.rule.WebRule;
+import org.openqa.selenium.WebDriver;
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.saml.processing.api.saml.v2.response.SAML2Response;
+import org.keycloak.saml.processing.core.saml.v2.constants.X500SAMLProfileConstants;
+import org.keycloak.dom.saml.v2.assertion.AssertionType;
+import org.keycloak.dom.saml.v2.assertion.AttributeStatementType;
+import org.keycloak.dom.saml.v2.assertion.AttributeType;
+import org.keycloak.dom.saml.v2.protocol.ResponseType;
+import org.keycloak.saml.processing.web.util.PostBindingUtil;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.ClientRequestContext;
+import javax.ws.rs.client.ClientRequestFilter;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class SamlBindingTest {
+
+ @ClassRule
+ public static SamlKeycloakRule keycloakRule = new SamlKeycloakRule() {
+ @Override
+ public void initWars() {
+ ClassLoader classLoader = SamlBindingTest.class.getClassLoader();
+
+ initializeSamlSecuredWar("/saml/simple-post", "/sales-post", "post.war", classLoader);
+ initializeSamlSecuredWar("/saml/signed-post", "/sales-post-sig", "post-sig.war", classLoader);
+ initializeSamlSecuredWar("/saml/signed-post-email", "/sales-post-sig-email", "post-sig-email.war", classLoader);
+ initializeSamlSecuredWar("/saml/signed-post-transient", "/sales-post-sig-transient", "post-sig-transient.war", classLoader);
+ initializeSamlSecuredWar("/saml/signed-post-persistent", "/sales-post-sig-persistent", "post-sig-persistent.war", classLoader);
+ initializeSamlSecuredWar("/saml/signed-metadata", "/sales-metadata", "post-metadata.war", classLoader);
+ initializeSamlSecuredWar("/saml/signed-get", "/employee-sig", "employee-sig.war", classLoader);
+ //initializeSamlSecuredWar("/saml/simple-get", "/employee", "employee.war", classLoader);
+ initializeSamlSecuredWar("/saml/signed-front-get", "/employee-sig-front", "employee-sig-front.war", classLoader);
+ initializeSamlSecuredWar("/saml/bad-client-signed-post", "/bad-client-sales-post-sig", "bad-client-post-sig.war", classLoader);
+ initializeSamlSecuredWar("/saml/bad-realm-signed-post", "/bad-realm-sales-post-sig", "bad-realm-post-sig.war", classLoader);
+ initializeSamlSecuredWar("/saml/encrypted-post", "/sales-post-enc", "post-enc.war", classLoader);
+ uploadSP();
+ server.getServer().deploy(createDeploymentInfo("employee.war", "/employee", SamlSPFacade.class));
+
+
+
+ }
+
+ @Override
+ public String getRealmJson() {
+ return "/saml/testsaml.json";
+ }
+ };
+
+ public static class SamlSPFacade extends HttpServlet {
+ public static String samlResponse;
+ public static String RELAY_STATE = "http://test.com/foo/bar";
+ public static String sentRelayState;
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ handler(req, resp);
+ }
+
+ @Override
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ handler(req, resp);
+ }
+
+ private void handler(HttpServletRequest req, HttpServletResponse resp) {
+ System.out.println("********* HERE ******");
+ if (req.getParameterMap().isEmpty()) {
+ System.out.println("redirecting");
+ resp.setStatus(302);
+ // Redirect
+ // UriBuilder builder = UriBuilder.fromUri("http://localhost:8081/auth/realms/demo/protocol/saml?SAMLRequest=jVLRTsIwFP2Vpe%2BjG4wxG0YyWYxL0BBAH3wx3XYnTbp29nYof%2B8YEvEBNOlD03vOveec2ynyWjYsae1WreC9BbTOZy0Vsr4Qk9YopjkKZIrXgMwWbJ08LNhw4LHGaKsLLcmRch3MEcFYoRVxktN1rhW2NZg1mJ0o4Gm1iMnW2oZRKnXB5VajZZEX%2BRTqRuo9ACVO2mkUih%2F4l9C8s0MNcFkjLaHW9KSUHlwR506bAnrPMam4RCBOlsYkS1%2BD3MvLcDJxAx9KN4jCkXszrG5cP%2BCVH4y8IM8PYFx2dsQOfuiILWQKLVc2JkPPH7te6HrRxh%2BzUdidwSSIXoiz%2FBZyK1Qp1Nv1yPIjCNn9ZrN0V1AKA4UlzjMY7N13IDKbHjyxXoA5291%2FtzH7I%2FApPet%2FHNawx65hli61FMXeSaTUH%2FMubtvlYU0LfcA1t5cl%2BAO%2FfxGlW%2FVQ1ipsoBCVgJLQ2XHo7385%2BwI%3D");
+ UriBuilder builder = UriBuilder.fromUri("http://localhost:8081/auth/realms/demo/protocol/saml?SAMLRequest=jVJbT8IwFP4rS99HuwluNIwEIUYSLwugD76Y2h2kSdfOng7l31uGRn0ATfrQ9HznfJfTEYpaN3zS%2Bo1ZwGsL6KP3WhvkXaEgrTPcClTIjagBuZd8Obm55mmP8cZZb6XV5NByGiwQwXllDYkmX9epNdjW4JbgtkrC%2FeK6IBvvG06ptlLojUXPc5YnFOpG2x0AJdEsaFRG7PuPoUWwQx0IXSOtoLb0SynduyLRpXUSOs8FWQuNQKL5rCDz2VO%2FymEgIY2zlJ3H%2FSx9jkU%2BzOK0ys8yNmSSsUEAYxnsqC18tyO2MDfohfEFSVkyiNlZzM5XacrDSbJePug%2Fkqj8FHKhTKXMy%2BnIng8g5FerVRmXd8sViR7AYec8AMh4tPfDO3L3Y2%2F%2F3cT4j7BH9Mf8A1nDb8PA%2Bay0WsldNNHavk1D1D5k4V0LXbi18MclJL2ke1FVvO6gvDXYgFRrBRWh4wPp7z85%2FgA%3D");
+ builder.queryParam("RelayState", RELAY_STATE);
+ resp.setHeader("Location", builder.build().toString());
+ return;
+ }
+ System.out.println("received response");
+ samlResponse = req.getParameter("SAMLResponse");
+ sentRelayState = req.getParameter("RelayState");
+ }
+ }
+
+ @Rule
+ public WebRule webRule = new WebRule(this);
+ @WebResource
+ protected WebDriver driver;
+ @WebResource
+ protected LoginPage loginPage;
+
+ protected void checkLoggedOut(String mainUrl) {
+ String pageSource = driver.getPageSource();
+ System.out.println("*** logout pagesouce ***");
+ System.out.println(pageSource);
+ System.out.println("driver url: " + driver.getCurrentUrl());
+ Assert.assertTrue(pageSource.contains("request-path: /logout.jsp"));
+ driver.navigate().to(mainUrl);
+ Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
+ }
+
+
+ @Test
+ public void testPostSimpleLoginLogout() {
+ driver.navigate().to("http://localhost:8081/sales-post/");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post/");
+ System.out.println(driver.getPageSource());
+ Assert.assertTrue(driver.getPageSource().contains("bburke"));
+ driver.navigate().to("http://localhost:8081/sales-post?GLO=true");
+ checkLoggedOut("http://localhost:8081/sales-post/");
+ }
+ @Test
+ public void testPostSignedLoginLogout() {
+ driver.navigate().to("http://localhost:8081/sales-post-sig/");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig/");
+ Assert.assertTrue(driver.getPageSource().contains("bburke"));
+ driver.navigate().to("http://localhost:8081/sales-post-sig?GLO=true");
+ checkLoggedOut("http://localhost:8081/sales-post-sig/");
+
+ }
+ @Test
+ public void testPostSignedLoginLogoutTransientNameID() {
+ driver.navigate().to("http://localhost:8081/sales-post-sig-transient/");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig-transient/");
+ System.out.println(driver.getPageSource());
+ Assert.assertFalse(driver.getPageSource().contains("bburke"));
+ Assert.assertTrue(driver.getPageSource().contains("principal=G-"));
+ driver.navigate().to("http://localhost:8081/sales-post-sig-transient?GLO=true");
+ checkLoggedOut("http://localhost:8081/sales-post-sig-transient/");
+
+ }
+ @Test
+ public void testPostSignedLoginLogoutPersistentNameID() {
+ driver.navigate().to("http://localhost:8081/sales-post-sig-persistent/");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig-persistent/");
+ System.out.println(driver.getPageSource());
+ Assert.assertFalse(driver.getPageSource().contains("bburke"));
+ Assert.assertTrue(driver.getPageSource().contains("principal=G-"));
+ driver.navigate().to("http://localhost:8081/sales-post-sig-persistent?GLO=true");
+ checkLoggedOut("http://localhost:8081/sales-post-sig-persistent/");
+
+ }
+ @Test
+ public void testPostSignedLoginLogoutEmailNameID() {
+ driver.navigate().to("http://localhost:8081/sales-post-sig-email/");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig-email/");
+ System.out.println(driver.getPageSource());
+ Assert.assertTrue(driver.getPageSource().contains("principal=bburke@redhat.com"));
+ driver.navigate().to("http://localhost:8081/sales-post-sig-email?GLO=true");
+ checkLoggedOut("http://localhost:8081/sales-post-sig-email/");
+
+ }
+
+ @Test
+ public void testRelayStateEncoding() throws Exception {
+ // this test has a hardcoded SAMLRequest and we hack a SP face servlet to get the SAMLResponse so we can look
+ // at the relay state
+ SamlSPFacade.samlResponse = null;
+ driver.navigate().to("http://localhost:8081/employee/");
+ Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
+ System.out.println(driver.getCurrentUrl());
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee/");
+ Assert.assertEquals(SamlSPFacade.sentRelayState, SamlSPFacade.RELAY_STATE);
+ Assert.assertNotNull(SamlSPFacade.samlResponse);
+
+ }
+
+
+ @Test
+ public void testAttributes() throws Exception {
+ // this test has a hardcoded SAMLRequest and we hack a SP face servlet to get the SAMLResponse so we can look
+ // at the assertions sent. This is because Picketlink, AFAICT, does not give you any way to get access to
+ // the assertion.
+
+ {
+ SamlSPFacade.samlResponse = null;
+ driver.navigate().to("http://localhost:8081/employee/");
+ Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
+ System.out.println(driver.getCurrentUrl());
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee/");
+ Assert.assertNotNull(SamlSPFacade.samlResponse);
+ SAML2Response saml2Response = new SAML2Response();
+ byte[] samlResponse = PostBindingUtil.base64Decode(SamlSPFacade.samlResponse);
+ ResponseType rt = saml2Response.getResponseType(new ByteArrayInputStream(samlResponse));
+ Assert.assertTrue(rt.getAssertions().size() == 1);
+ AssertionType assertion = rt.getAssertions().get(0).getAssertion();
+
+ // test attributes and roles
+
+ boolean email = false;
+ boolean phone = false;
+ boolean userRole = false;
+ boolean managerRole = false;
+ for (AttributeStatementType statement : assertion.getAttributeStatements()) {
+ for (AttributeStatementType.ASTChoiceType choice : statement.getAttributes()) {
+ AttributeType attr = choice.getAttribute();
+ if (X500SAMLProfileConstants.EMAIL.getFriendlyName().equals(attr.getFriendlyName())) {
+ Assert.assertEquals(X500SAMLProfileConstants.EMAIL.get(), attr.getName());
+ Assert.assertEquals(JBossSAMLURIConstants.ATTRIBUTE_FORMAT_URI.get(), attr.getNameFormat());
+ Assert.assertEquals(attr.getAttributeValue().get(0), "bburke@redhat.com");
+ email = true;
+ } else if (attr.getName().equals("phone")) {
+ Assert.assertEquals(JBossSAMLURIConstants.ATTRIBUTE_FORMAT_BASIC.get(), attr.getNameFormat());
+ Assert.assertEquals(attr.getAttributeValue().get(0), "617");
+ phone = true;
+ } else if (attr.getName().equals("Role")) {
+ if (attr.getAttributeValue().get(0).equals("manager")) managerRole = true;
+ if (attr.getAttributeValue().get(0).equals("user")) userRole = true;
+ }
+ }
+
+ }
+
+ Assert.assertTrue(email);
+ Assert.assertTrue(phone);
+ Assert.assertTrue(userRole);
+ Assert.assertTrue(managerRole);
+ }
+
+ keycloakRule.update(new KeycloakRule.KeycloakSetup() {
+ @Override
+ public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+ ClientModel app = appRealm.getClientByClientId("http://localhost:8081/employee/");
+ for (ProtocolMapperModel mapper : app.getProtocolMappers()) {
+ if (mapper.getName().equals("role-list")) {
+ app.removeProtocolMapper(mapper);
+ mapper.setId(null);
+ mapper.getConfig().put(RoleListMapper.SINGLE_ROLE_ATTRIBUTE, "true");
+ mapper.getConfig().put(AttributeStatementHelper.SAML_ATTRIBUTE_NAME, "memberOf");
+ app.addProtocolMapper(mapper);
+ }
+ }
+ app.addProtocolMapper(HardcodedAttributeMapper.create("hardcoded-attribute", "hardcoded-attribute", "Basic", null, "hard", false, null));
+ app.addProtocolMapper(HardcodedRole.create("hardcoded-role", "hardcoded-role"));
+ app.addProtocolMapper(RoleNameMapper.create("renamed-role", "manager", "el-jefe"));
+ app.addProtocolMapper(RoleNameMapper.create("renamed-employee-role", "http://localhost:8081/employee/.employee", "pee-on"));
+ }
+ }, "demo");
+
+ System.out.println(">>>>>>>>>> single role attribute <<<<<<<<");
+
+ {
+ SamlSPFacade.samlResponse = null;
+ driver.navigate().to("http://localhost:8081/employee/");
+ System.out.println(driver.getCurrentUrl());
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee/");
+ Assert.assertNotNull(SamlSPFacade.samlResponse);
+ SAML2Response saml2Response = new SAML2Response();
+ byte[] samlResponse = PostBindingUtil.base64Decode(SamlSPFacade.samlResponse);
+ ResponseType rt = saml2Response.getResponseType(new ByteArrayInputStream(samlResponse));
+ Assert.assertTrue(rt.getAssertions().size() == 1);
+ AssertionType assertion = rt.getAssertions().get(0).getAssertion();
+
+ // test attributes and roles
+
+ boolean userRole = false;
+ boolean managerRole = false;
+ boolean single = false;
+ boolean hardcodedRole = false;
+ boolean hardcodedAttribute = false;
+ boolean peeOn = false;
+ for (AttributeStatementType statement : assertion.getAttributeStatements()) {
+ for (AttributeStatementType.ASTChoiceType choice : statement.getAttributes()) {
+ AttributeType attr = choice.getAttribute();
+ if (attr.getName().equals("memberOf")) {
+ if (single) Assert.fail("too many role attributes");
+ single = true;
+ for (Object value : attr.getAttributeValue()) {
+ if (value.equals("el-jefe")) managerRole = true;
+ if (value.equals("user")) userRole = true;
+ if (value.equals("hardcoded-role")) hardcodedRole = true;
+ if (value.equals("pee-on")) peeOn = true;
+ }
+ } else if (attr.getName().equals("hardcoded-attribute")) {
+ hardcodedAttribute = true;
+ Assert.assertEquals(attr.getAttributeValue().get(0), "hard");
+ }
+ }
+
+ }
+
+ Assert.assertTrue(single);
+ Assert.assertTrue(hardcodedAttribute);
+ Assert.assertTrue(hardcodedRole);
+ Assert.assertTrue(peeOn);
+ Assert.assertTrue(userRole);
+ Assert.assertTrue(managerRole);
+ }
+ }
+
+ @Test
+ public void testRedirectSignedLoginLogout() {
+ driver.navigate().to("http://localhost:8081/employee-sig/");
+ Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee-sig/");
+ Assert.assertTrue(driver.getPageSource().contains("bburke"));
+ driver.navigate().to("http://localhost:8081/employee-sig?GLO=true");
+ checkLoggedOut("http://localhost:8081/employee-sig/");
+
+ }
+
+ @Test
+ public void testRedirectSignedLoginLogoutFrontNoSSO() {
+ driver.navigate().to("http://localhost:8081/employee-sig-front/");
+ Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee-sig-front/");
+ Assert.assertTrue(driver.getPageSource().contains("bburke"));
+ driver.navigate().to("http://localhost:8081/employee-sig-front?GLO=true");
+ checkLoggedOut("http://localhost:8081/employee-sig-front/");
+
+ }
+
+ @Test
+ public void testRedirectSignedLoginLogoutFront() {
+ // visit 1st app an logg in
+ System.out.println("visit 1st app ");
+ driver.navigate().to("http://localhost:8081/employee-sig/");
+ Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
+ System.out.println("login to form");
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee-sig/");
+ Assert.assertTrue(driver.getPageSource().contains("bburke"));
+
+ // visit 2nd app
+ System.out.println("visit 2nd app ");
+ driver.navigate().to("http://localhost:8081/employee-sig-front/");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee-sig-front/");
+ Assert.assertTrue(driver.getPageSource().contains("bburke"));
+
+ // visit 3rd app
+ System.out.println("visit 3rd app ");
+ driver.navigate().to("http://localhost:8081/sales-post-sig/");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig/");
+ Assert.assertTrue(driver.getPageSource().contains("bburke"));
+
+ // logout of first app
+ System.out.println("GLO");
+ driver.navigate().to("http://localhost:8081/employee-sig?GLO=true");
+ checkLoggedOut("http://localhost:8081/employee-sig/");
+ driver.navigate().to("http://localhost:8081/employee-sig-front/");
+ Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
+ driver.navigate().to("http://localhost:8081/sales-post-sig/");
+ Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
+
+ }
+
+ @Test
+ public void testPostEncryptedLoginLogout() {
+ driver.navigate().to("http://localhost:8081/sales-post-enc/");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-enc/");
+ Assert.assertTrue(driver.getPageSource().contains("bburke"));
+ driver.navigate().to("http://localhost:8081/sales-post-enc?GLO=true");
+ checkLoggedOut("http://localhost:8081/sales-post-enc/");
+
+ }
+ @Test
+ public void testPostBadClientSignature() {
+ driver.navigate().to("http://localhost:8081/bad-client-sales-post-sig/");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
+ Assert.assertEquals(driver.getTitle(), "We're sorry...");
+
+ }
+
+ @Test
+ public void testPostBadRealmSignature() {
+ driver.navigate().to("http://localhost:8081/bad-realm-sales-post-sig/");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/bad-realm-sales-post-sig/");
+ Assert.assertTrue(driver.getPageSource().contains("null"));
+ }
+
+ private static String createToken() {
+ KeycloakSession session = keycloakRule.startSession();
+ try {
+ RealmManager manager = new RealmManager(session);
+
+ RealmModel adminRealm = manager.getRealm(Config.getAdminRealm());
+ ClientModel adminConsole = adminRealm.getClientByClientId(Constants.ADMIN_CONSOLE_CLIENT_ID);
+ TokenManager tm = new TokenManager();
+ UserModel admin = session.users().getUserByUsername("admin", adminRealm);
+ ClientSessionModel clientSession = session.sessions().createClientSession(adminRealm, adminConsole);
+ clientSession.setNote(OIDCLoginProtocol.ISSUER, "http://localhost:8081/auth/realms/master");
+ UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, "admin", null, "form", false, null, null);
+ AccessToken token = tm.createClientAccessToken(session, tm.getAccess(null, adminConsole, admin), adminRealm, adminConsole, admin, userSession, clientSession);
+ return tm.encodeToken(adminRealm, token);
+ } finally {
+ keycloakRule.stopSession(session, true);
+ }
+ }
+
+
+ @Test
+ public void testMetadataPostSignedLoginLogout() throws Exception {
+
+ driver.navigate().to("http://localhost:8081/sales-metadata/");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
+ loginPage.login("bburke", "password");
+ Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-metadata/");
+ String pageSource = driver.getPageSource();
+ Assert.assertTrue(pageSource.contains("bburke"));
+ driver.navigate().to("http://localhost:8081/sales-metadata?GLO=true");
+ checkLoggedOut("http://localhost:8081/sales-metadata/");
+
+ }
+
+ public static void uploadSP() {
+ String token = createToken();
+ final String authHeader = "Bearer " + token;
+ ClientRequestFilter authFilter = new ClientRequestFilter() {
+ @Override
+ public void filter(ClientRequestContext requestContext) throws IOException {
+ requestContext.getHeaders().add(HttpHeaders.AUTHORIZATION, authHeader);
+ }
+ };
+ Client client = ClientBuilder.newBuilder().register(authFilter).build();
+ UriBuilder authBase = UriBuilder.fromUri("http://localhost:8081/auth");
+ WebTarget adminRealms = client.target(AdminRoot.realmsUrl(authBase));
+
+
+ MultipartFormDataOutput formData = new MultipartFormDataOutput();
+ InputStream is = SamlBindingTest.class.getResourceAsStream("/saml/sp-metadata.xml");
+ Assert.assertNotNull(is);
+ formData.addFormData("file", is, MediaType.APPLICATION_XML_TYPE);
+
+ WebTarget upload = adminRealms.path("demo/client-importers/saml2-entity-descriptor/upload");
+ System.out.println(upload.getUri());
+ Response response = upload.request().post(Entity.entity(formData, MediaType.MULTIPART_FORM_DATA));
+ Assert.assertEquals(204, response.getStatus());
+ response.close();
+ client.close();
+ }
+
+
+}
diff --git a/testsuite/integration/src/test/resources/log4j.properties b/testsuite/integration/src/test/resources/log4j.properties
index a776341..c4ff48b 100755
--- a/testsuite/integration/src/test/resources/log4j.properties
+++ b/testsuite/integration/src/test/resources/log4j.properties
@@ -14,8 +14,11 @@ log4j.logger.org.keycloak=info
# log4j.logger.org.keycloak.provider.ProviderManager=debug
# log4j.logger.org.keycloak.provider.FileSystemProviderLoaderFactory=debug
+# Liquibase updates logged with "info" by default. Logging level can be changed by system property "keycloak.liquibase.logging.level"
+keycloak.liquibase.logging.level=info
+log4j.logger.org.keycloak.connections.jpa.updater.liquibase.LiquibaseJpaUpdaterProvider=${keycloak.liquibase.logging.level}
+
# Enable to view database updates
-# log4j.logger.org.keycloak.connections.jpa.updater.liquibase.LiquibaseJpaUpdaterProvider=debug
# log4j.logger.org.keycloak.connections.mongo.updater.DefaultMongoUpdaterProvider=debug
# log4j.logger.org.keycloak.connections.jpa.DefaultJpaConnectionProviderFactory=debug
# log4j.logger.org.keycloak.migration.MigrationModelManager=debug
diff --git a/testsuite/integration/src/test/resources/saml/signed-get/WEB-INF/picketlink.xml b/testsuite/integration/src/test/resources/saml/signed-get/WEB-INF/picketlink.xml
index e2e7e3b..2dd9522 100755
--- a/testsuite/integration/src/test/resources/saml/signed-get/WEB-INF/picketlink.xml
+++ b/testsuite/integration/src/test/resources/saml/signed-get/WEB-INF/picketlink.xml
@@ -1,6 +1,6 @@
<PicketLink xmlns="urn:picketlink:identity-federation:config:2.1">
<PicketLinkSP xmlns="urn:picketlink:identity-federation:config:2.1"
- ServerEnvironment="tomcat" BindingType="REDIRECT" SupportsSignatures="true">
+ ServerEnvironment="tomcat" BindingType="REDIRECT" SupportsSignatures="true" IDPUsesPostBinding="false">
<IdentityURL>${idp-sig.url::http://localhost:8081/auth/realms/demo/protocol/saml}
</IdentityURL>
<ServiceURL>${employee-sig.url::http://localhost:8081/employee-sig/}
diff --git a/testsuite/integration/src/test/resources/saml/simple-get/WEB-INF/picketlink.xml b/testsuite/integration/src/test/resources/saml/simple-get/WEB-INF/picketlink.xml
index 7636260..ade45d1 100755
--- a/testsuite/integration/src/test/resources/saml/simple-get/WEB-INF/picketlink.xml
+++ b/testsuite/integration/src/test/resources/saml/simple-get/WEB-INF/picketlink.xml
@@ -1,6 +1,6 @@
<PicketLink xmlns="urn:picketlink:identity-federation:config:2.1">
<PicketLinkSP xmlns="urn:picketlink:identity-federation:config:2.1"
- ServerEnvironment="tomcat" BindingType="REDIRECT" RelayState="someURL">
+ ServerEnvironment="tomcat" BindingType="REDIRECT" IDPUsesPostBinding="false">
<IdentityURL>${idp.url::http://localhost:8081/auth/realms/demo/protocol/saml}</IdentityURL>
<ServiceURL>${employee.url::http://localhost:8081/employee/}
</ServiceURL>
diff --git a/testsuite/integration-arquillian/pom.xml b/testsuite/integration-arquillian/pom.xml
index 2435a1a..c297bdd 100644
--- a/testsuite/integration-arquillian/pom.xml
+++ b/testsuite/integration-arquillian/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-testsuite-pom</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/fragment/Navigation.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/fragment/Navigation.java
index 4175c45..2ef3a69 100644
--- a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/fragment/Navigation.java
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/fragment/Navigation.java
@@ -15,7 +15,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.keycloak.testsuite.ui.fragment;
import org.jboss.arquillian.drone.api.annotation.Drone;
@@ -33,9 +32,9 @@ import org.openqa.selenium.WebElement;
* @author Petr Mensik
*/
public class Navigation {
-
- @Drone
- private WebDriver driver;
+
+ @Drone
+ private WebDriver driver;
@FindByJQuery("a:contains('Settings')")
private WebElement settingsLink;
@@ -54,8 +53,8 @@ public class Navigation {
@FindByJQuery("a:contains('Tokens')")
private WebElement tokensLink;
-
- @FindByJQuery("a:contains('Sessions')")
+
+ @FindByJQuery("a:contains('Sessions')")
private WebElement sessionLink;
@FindByJQuery("a:contains('Security Defenses')")
@@ -63,32 +62,32 @@ public class Navigation {
@FindByJQuery("a:contains('Events')")
private WebElement eventsLink;
-
- @FindByJQuery("a:contains('Login')")
+
+ @FindByJQuery("a:contains('Login')")
private WebElement loginLink;
@FindByJQuery("a:contains('Themes')")
private WebElement themesLink;
- @FindByJQuery("a:contains('Role Mappings')")
+ @FindByJQuery("a:contains('Role Mappings')")
private WebElement usersRoleMappings;
-
- @FindByJQuery("a:contains('Add Realm')")
+
+ @FindByJQuery("a:contains('Add Realm')")
private WebElement addRealm;
-
- @FindByJQuery("a:contains('Credentials')")
+
+ @FindByJQuery("a:contains('Credentials')")
private WebElement credentials;
-
- @FindByJQuery("a:contains('Attributes')")
+
+ @FindByJQuery("a:contains('Attributes')")
private WebElement attributes;
-
+
@FindBy(css = "div h1")
private WebElement currentHeader;
- public void selectRealm(String realmName) {
- driver.findElement(By.linkText(realmName)).click();
- }
-
+ public void selectRealm(String realmName) {
+ driver.findElement(By.linkText(realmName)).click();
+ }
+
public void settings() {
openPage(settingsLink, "Settings");
}
@@ -104,7 +103,7 @@ public class Navigation {
public void clients() {
openPage(clientsLink, "Clients");
}
-
+
public void oauth() {
openPage(oauthLink, "OAuth Clients");
}
@@ -112,10 +111,10 @@ public class Navigation {
public void tokens() {
openPage(tokensLink, "Settings");
}
-
- public void sessions() {
- openPage(sessionLink, "Sessions");
- }
+
+ public void sessions() {
+ openPage(sessionLink, "Sessions");
+ }
public void security() {
openPage(securityLink, "Settings");
@@ -124,30 +123,32 @@ public class Navigation {
public void events() {
openPage(eventsLink, "Events");
}
-
- public void login() {
- openPage(loginLink, "Settings");
- }
-
- public void themes() {
- openPage(themesLink, "Settings");
- }
-
- public void roleMappings() {
- openPage(usersRoleMappings, "User");
- }
-
- public void addRealm() {
- openPage(addRealm, "Add Realm");
- }
-
- public void credentials() {
- openPage(credentials, "Settings");
- }
-
- public void attributes() {
- openPage(attributes, "Attributes");
- }
+
+ public void login() {
+ openPage(loginLink, "Settings");
+ }
+
+ public void themes() {
+ openPage(themesLink, "Settings");
+ }
+
+ public void roleMappings(String username) {
+ String usernameCapitalized = Character.toUpperCase(username.charAt(0))
+ + username.substring(1);
+ openPage(usersRoleMappings, usernameCapitalized);
+ }
+
+ public void addRealm() {
+ openPage(addRealm, "Add Realm");
+ }
+
+ public void credentials() {
+ openPage(credentials, "Settings");
+ }
+
+ public void attributes() {
+ openPage(attributes, "Attributes");
+ }
private void openPage(WebElement page, String headerText) {
waitGuiForElement(page);
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/user/RoleMappingsPage.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/user/RoleMappingsPage.java
new file mode 100644
index 0000000..3b92314
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/page/settings/user/RoleMappingsPage.java
@@ -0,0 +1,71 @@
+package org.keycloak.testsuite.ui.page.settings.user;
+
+import org.keycloak.testsuite.ui.page.AbstractPage;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.ui.Select;
+
+import static org.keycloak.testsuite.ui.util.SeleniumUtils.waitGuiForElement;
+
+/**
+ * Created by fkiss.
+ */
+public class RoleMappingsPage extends AbstractPage {
+
+ @FindBy(id = "available")
+ private Select availableRolesSelect;
+
+ @FindBy(id = "assigned")
+ private Select assignedRolesSelect;
+
+ @FindBy(id = "realm-composite")
+ private Select effectiveRolesSelect;
+
+ @FindBy(id = "available-client")
+ private Select availableClientRolesSelect;
+
+ @FindBy(id = "assigned-client")
+ private Select assignedClientRolesSelect;
+
+ @FindBy(css = "button[ng-click*='addRealm']")
+ private WebElement addSelected;
+
+ @FindBy(css = "button[ng-click*='addRealm']")
+ private WebElement addSelectedButton;
+
+ @FindBy(css = "button[ng-click*='deleteRealm']")
+ private WebElement removeSelectedButton;
+
+ @FindBy(id = "clients")
+ private Select clientRolesSelect;
+
+ public void addAvailableRole(String role){
+ waitGuiForElement(By.id("available"));
+ availableRolesSelect.selectByVisibleText(role);
+ addSelected.click();
+ }
+
+ public void removeAssignedRole(String client){
+ waitGuiForElement(By.id("assigned"));
+ assignedRolesSelect.selectByVisibleText(client);
+ removeSelectedButton.click();
+ }
+
+ public void selectClientRole(String client){
+ waitGuiForElement(By.id("clients"));
+ clientRolesSelect.selectByVisibleText(client);
+ }
+
+ public void addAvailableClientRole(String role){
+ waitGuiForElement(By.id("available-client"));
+ availableRolesSelect.selectByVisibleText(role);
+ addSelected.click();
+ }
+
+ public void removeAssignedClientRole(String client){
+ waitGuiForElement(By.id("assigned-client"));
+ assignedClientRolesSelect.selectByVisibleText(client);
+ removeSelectedButton.click();
+ }
+}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/role/AddNewRoleTest.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/role/AddNewRoleTest.java
index 7bcd681..dcd0038 100644
--- a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/role/AddNewRoleTest.java
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/role/AddNewRoleTest.java
@@ -3,7 +3,6 @@
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
-
package org.keycloak.testsuite.ui.test.role;
import org.jboss.arquillian.graphene.findby.FindByJQuery;
@@ -17,40 +16,39 @@ import org.junit.Before;
import org.junit.Ignore;
import org.keycloak.testsuite.ui.AbstractKeyCloakTest;
import org.keycloak.testsuite.ui.fragment.FlashMessage;
-import org.keycloak.testsuite.ui.page.settings.UserPage;
+import org.keycloak.testsuite.ui.page.settings.user.UserPage;
import static org.openqa.selenium.By.id;
import org.openqa.selenium.support.ui.Select;
-
/**
*
* @author Petr Mensik
*/
public class AddNewRoleTest extends AbstractKeyCloakTest<RolesPage> {
-
- @Page
- private UserPage userPage;
-
- @FindByJQuery(".alert")
+
+ @Page
+ private UserPage userPage;
+
+ @FindByJQuery(".alert")
private FlashMessage flashMessage;
-
- @Before
- public void beforeTestAddNewRole() {
- navigation.roles();
- }
-
+
+ @Before
+ public void beforeTestAddNewRole() {
+ navigation.roles();
+ }
+
@Test
public void testAddNewRole() {
Role role = new Role("role1");
page.addRole(role);
- flashMessage.waitUntilPresent();
- assertTrue(flashMessage.getText(), flashMessage.isSuccess());
- navigation.roles();
+ flashMessage.waitUntilPresent();
+ assertTrue(flashMessage.getText(), flashMessage.isSuccess());
+ navigation.roles();
assertEquals("role1", page.findRole(role.getName()).getName());
page.deleteRole(role);
}
-
- @Ignore
+
+ @Ignore
@Test
public void testAddNewRoleWithLongName() {
String name = "hjewr89y1894yh98(*&*&$jhjkashd)*(&y8934h*&@#hjkahsdj";
@@ -59,36 +57,36 @@ public class AddNewRoleTest extends AbstractKeyCloakTest<RolesPage> {
navigation.roles();
page.deleteRole(name);
}
-
+
@Test
public void testAddExistingRole() {
Role role = new Role("role2");
page.addRole(role);
- flashMessage.waitUntilPresent();
- assertTrue(flashMessage.getText(), flashMessage.isSuccess());
+ flashMessage.waitUntilPresent();
+ assertTrue(flashMessage.getText(), flashMessage.isSuccess());
navigation.roles();
page.addRole(role);
- flashMessage.waitUntilPresent();
- assertTrue(flashMessage.getText(), flashMessage.isDanger());
+ flashMessage.waitUntilPresent();
+ assertTrue(flashMessage.getText(), flashMessage.isDanger());
navigation.roles();
page.deleteRole(role);
}
-
- @Test
- public void testRoleIsAvailableForUsers() {
- Role role = new Role("User role");
- page.addRole(role);
- flashMessage.waitUntilPresent();
- assertTrue(flashMessage.getText(), flashMessage.isSuccess());
- navigation.users();
- userPage.showAllUsers();
- userPage.goToUser("admin");
- navigation.roleMappings();
- Select rolesSelect = new Select(driver.findElement(id("available")));
- assertEquals("User role should be present in admin role mapping",
- role.getName(), rolesSelect.getOptions().get(0).getText());
- navigation.roles();
- page.deleteRole(role);
- }
-
+
+ @Test
+ public void testRoleIsAvailableForUsers() {
+ Role role = new Role("User role");
+ page.addRole(role);
+ flashMessage.waitUntilPresent();
+ assertTrue(flashMessage.getText(), flashMessage.isSuccess());
+ navigation.users();
+ userPage.showAllUsers();
+ userPage.goToUser("admin");
+ navigation.roleMappings("Admin");
+ Select rolesSelect = new Select(driver.findElement(id("available")));
+ assertEquals("User role should be present in admin role mapping",
+ role.getName(), rolesSelect.getOptions().get(0).getText());
+ navigation.roles();
+ page.deleteRole(role);
+ }
+
}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/user/AddNewUserTest.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/user/AddNewUserTest.java
index 5694c51..f65cc15 100644
--- a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/user/AddNewUserTest.java
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/user/AddNewUserTest.java
@@ -22,7 +22,7 @@ import org.jboss.arquillian.graphene.findby.FindByJQuery;
import org.junit.Test;
import org.keycloak.testsuite.ui.fragment.FlashMessage;
import org.keycloak.testsuite.ui.model.User;
-import org.keycloak.testsuite.ui.page.settings.UserPage;
+import org.keycloak.testsuite.ui.page.settings.user.UserPage;
import static org.junit.Assert.*;
@@ -100,13 +100,16 @@ public class AddNewUserTest extends AbstractKeyCloakTest<UserPage> {
@Test
public void addDisabledUser() {
- page.addUser(TEST_USER1);
+ User disabledUser = new User(TEST_USER1);
+ disabledUser.setUserEnabled(false);
+ disabledUser.setUserName("disabled_user");
+ page.addUser(disabledUser);
assertTrue(flashMessage.getText(), flashMessage.isSuccess());
navigation.users();
- page.deleteUser(TEST_USER1.getUserName());
+ page.deleteUser(disabledUser.getUserName());
flashMessage.waitUntilPresent();
assertTrue(flashMessage.getText(), flashMessage.isSuccess());
- assertNull(page.findUser(TEST_USER1.getUserName()));
+ assertNull(page.findUser(disabledUser.getUserName()));
}
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/user/RegisterNewUserTest.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/user/RegisterNewUserTest.java
index 834ba25..981c531 100644
--- a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/user/RegisterNewUserTest.java
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/user/RegisterNewUserTest.java
@@ -25,7 +25,7 @@ import org.junit.Test;
import org.keycloak.testsuite.ui.fragment.FlashMessage;
import org.keycloak.testsuite.ui.model.User;
import org.keycloak.testsuite.ui.page.RegisterPage;
-import org.keycloak.testsuite.ui.page.settings.UserPage;
+import org.keycloak.testsuite.ui.page.settings.user.UserPage;
import static org.junit.Assert.*;
import org.junit.Before;
diff --git a/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/user/RoleMappingsTest.java b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/user/RoleMappingsTest.java
new file mode 100644
index 0000000..157153f
--- /dev/null
+++ b/testsuite/integration-arquillian/src/test/java/org/keycloak/testsuite/ui/test/user/RoleMappingsTest.java
@@ -0,0 +1,72 @@
+package org.keycloak.testsuite.ui.test.user;
+
+import org.jboss.arquillian.graphene.findby.FindByJQuery;
+import org.jboss.arquillian.graphene.page.Page;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.keycloak.testsuite.ui.AbstractKeyCloakTest;
+import org.keycloak.testsuite.ui.fragment.FlashMessage;
+import org.keycloak.testsuite.ui.model.User;
+import org.keycloak.testsuite.ui.page.settings.user.RoleMappingsPage;
+import org.keycloak.testsuite.ui.page.settings.user.UserPage;
+
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.openqa.selenium.By.linkText;
+
+/**
+ * Created by fkiss.
+ */
+public class RoleMappingsTest extends AbstractKeyCloakTest<RoleMappingsPage> {
+
+ @Page
+ private UserPage userPage;
+
+ @FindByJQuery(".alert")
+ private FlashMessage flashMessage;
+
+ @Before
+ public void beforeAddNewUserTest() {
+ navigation.users();
+ }
+
+ @Test
+ public void addUserAndAssignRole() {
+ String testUsername = "tester1";
+ User testUser = new User(testUsername, "pass");
+ userPage.addUser(testUser);
+ flashMessage.waitUntilPresent();
+ assertTrue(flashMessage.getText(), flashMessage.isSuccess());
+ navigation.users();
+ userPage.findUser(testUsername);
+ driver.findElement(linkText(testUsername)).click();
+ navigation.roleMappings(testUsername);
+
+ page.addAvailableRole("create-realm");
+ assertTrue(flashMessage.getText(), flashMessage.isSuccess());
+ navigation.users();
+ userPage.deleteUser(testUsername);
+ }
+
+ @Ignore
+ @Test
+ public void addAndRemoveUserAndAssignRole() {
+ String testUsername = "tester2";
+ User testUser = new User(testUsername, "pass");
+ userPage.addUser(testUser);
+ flashMessage.waitUntilPresent();
+ assertTrue(flashMessage.getText(), flashMessage.isSuccess());
+ navigation.users();
+ userPage.findUser(testUsername);
+ driver.findElement(linkText(testUsername)).click();
+ navigation.roleMappings(testUsername);
+
+ page.addAvailableRole("create-realm");
+ assertTrue(flashMessage.getText(), flashMessage.isSuccess());
+ page.removeAssignedRole("create-realm");
+ assertTrue(flashMessage.getText(), flashMessage.isSuccess());
+ navigation.users();
+ userPage.deleteUser(testUsername);
+ }
+}
testsuite/jetty/jetty81/pom.xml 2(+1 -1)
diff --git a/testsuite/jetty/jetty81/pom.xml b/testsuite/jetty/jetty81/pom.xml
index 353d2d4..0ec5e04 100755
--- a/testsuite/jetty/jetty81/pom.xml
+++ b/testsuite/jetty/jetty81/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-testsuite-pom</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
testsuite/jetty/jetty91/pom.xml 2(+1 -1)
diff --git a/testsuite/jetty/jetty91/pom.xml b/testsuite/jetty/jetty91/pom.xml
index 7d9b913..93f1ef2 100755
--- a/testsuite/jetty/jetty91/pom.xml
+++ b/testsuite/jetty/jetty91/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-testsuite-pom</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
testsuite/jetty/jetty92/pom.xml 2(+1 -1)
diff --git a/testsuite/jetty/jetty92/pom.xml b/testsuite/jetty/jetty92/pom.xml
index 3f72eb1..352c387 100755
--- a/testsuite/jetty/jetty92/pom.xml
+++ b/testsuite/jetty/jetty92/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-testsuite-pom</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
testsuite/performance/pom.xml 2(+1 -1)
diff --git a/testsuite/performance/pom.xml b/testsuite/performance/pom.xml
index 5fcb5fc..77a5a72 100755
--- a/testsuite/performance/pom.xml
+++ b/testsuite/performance/pom.xml
@@ -5,7 +5,7 @@
<parent>
<artifactId>keycloak-testsuite-pom</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
testsuite/pom.xml 34(+33 -1)
diff --git a/testsuite/pom.xml b/testsuite/pom.xml
index d3db601..091d0ec 100755
--- a/testsuite/pom.xml
+++ b/testsuite/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -13,6 +13,38 @@
<packaging>pom</packaging>
<name>Keycloak TestSuite</name>
<description />
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.jboss.resteasy</groupId>
+ <artifactId>jaxrs-api</artifactId>
+ <version>${resteasy.latest.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.resteasy</groupId>
+ <artifactId>resteasy-jaxrs</artifactId>
+ <version>${resteasy.latest.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.resteasy</groupId>
+ <artifactId>resteasy-multipart-provider</artifactId>
+ <version>${resteasy.latest.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.resteasy</groupId>
+ <artifactId>resteasy-jackson-provider</artifactId>
+ <version>${resteasy.latest.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.resteasy</groupId>
+ <artifactId>async-http-servlet-3.0</artifactId>
+ <version>${resteasy.latest.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
<build>
<plugins>
<plugin>
testsuite/proxy/pom.xml 2(+1 -1)
diff --git a/testsuite/proxy/pom.xml b/testsuite/proxy/pom.xml
index 1643296..de6e1a0 100755
--- a/testsuite/proxy/pom.xml
+++ b/testsuite/proxy/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-testsuite-pom</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
testsuite/tomcat6/pom.xml 2(+1 -1)
diff --git a/testsuite/tomcat6/pom.xml b/testsuite/tomcat6/pom.xml
index d10d244..22a0d83 100755
--- a/testsuite/tomcat6/pom.xml
+++ b/testsuite/tomcat6/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-testsuite-pom</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
testsuite/tomcat7/pom.xml 2(+1 -1)
diff --git a/testsuite/tomcat7/pom.xml b/testsuite/tomcat7/pom.xml
index 20934d3..8dc36b4 100755
--- a/testsuite/tomcat7/pom.xml
+++ b/testsuite/tomcat7/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-testsuite-pom</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
testsuite/tomcat8/pom.xml 2(+1 -1)
diff --git a/testsuite/tomcat8/pom.xml b/testsuite/tomcat8/pom.xml
index 0377697..bf4c39a 100755
--- a/testsuite/tomcat8/pom.xml
+++ b/testsuite/tomcat8/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>keycloak-testsuite-pom</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
timer/api/pom.xml 2(+1 -1)
diff --git a/timer/api/pom.xml b/timer/api/pom.xml
index f51b947..23d6470 100755
--- a/timer/api/pom.xml
+++ b/timer/api/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-timer-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
timer/basic/pom.xml 2(+1 -1)
diff --git a/timer/basic/pom.xml b/timer/basic/pom.xml
index cde6e33..1017fce 100755
--- a/timer/basic/pom.xml
+++ b/timer/basic/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-timer-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
timer/pom.xml 2(+1 -1)
diff --git a/timer/pom.xml b/timer/pom.xml
index 912db1f..de37631 100755
--- a/timer/pom.xml
+++ b/timer/pom.xml
@@ -3,7 +3,7 @@
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
- <version>1.3.0.Final-SNAPSHOT</version>
+ <version>1.4.0.Final-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>