keycloak-uncached
Changes
connections/jpa-liquibase/pom.xml 2(+1 -1)
connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate1_2_0_Beta1.java 11(+6 -5)
connections/mongo-update/pom.xml 5(+0 -5)
connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update1_2_0_Beta1.java 17(+7 -10)
distribution/modules/src/main/resources/modules/org/keycloak/keycloak-connections-jpa-liquibase/main/module.xml 1(+0 -1)
distribution/modules/src/main/resources/modules/org/keycloak/keycloak-connections-mongo-update/main/module.xml 1(+0 -1)
examples/multi-tenant/src/main/java/org/keycloak/example/multitenant/boundary/ProtectedServlet.java 2(+1 -1)
export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java 2(+0 -2)
forms/common-themes/src/main/resources/theme/base/account/messages/messages_de.properties 48(+24 -24)
forms/common-themes/src/main/resources/theme/base/account/messages/messages_pt_BR.properties 52(+26 -26)
forms/common-themes/src/main/resources/theme/base/login/messages/messages_de.properties 112(+56 -56)
forms/common-themes/src/main/resources/theme/base/login/messages/messages_pt_BR.properties 160(+80 -80)
forms/common-themes/src/main/resources/theme/keycloak/email/messages/messages_de.properties 10(+5 -5)
forms/common-themes/src/main/resources/theme/keycloak/email/messages/messages_en.properties 6(+3 -3)
forms/common-themes/src/main/resources/theme/keycloak/email/messages/messages_pt_BR.properties 20(+10 -10)
forms/email-freemarker/src/main/java/org/keycloak/email/freemarker/FreeMarkerEmailProvider.java 6(+6 -0)
integration/adapter-core/src/main/java/org/keycloak/adapters/BearerTokenRequestAuthenticator.java 2(+1 -1)
integration/adapter-core/src/main/java/org/keycloak/adapters/jaas/AbstractKeycloakLoginModule.java 2(+1 -1)
integration/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java 2(+1 -1)
integration/adapter-core/src/main/java/org/keycloak/adapters/RefreshableKeycloakSecurityContext.java 2(+1 -1)
integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ApplicationResource.java 15(+3 -12)
integration/admin-client/src/main/java/org/keycloak/admin/client/resource/OAuthClientResource.java 24(+13 -11)
integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ProtocolMappersResource.java 55(+55 -0)
model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java 10(+0 -10)
model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedClient.java 6(+0 -6)
model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/MemoryUserCache.java 6(+4 -2)
services/src/main/java/org/keycloak/services/migration/DefaultMigrationProviderFactory.java 38(+38 -0)
services/src/main/resources/META-INF/services/org.keycloak.migration.MigrationProviderFactory 1(+1 -0)
testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java 6(+5 -1)
testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/RelativeUriAdapterTest.java 6(+5 -1)
testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractIdentityProviderTest.java 2(+1 -1)
testsuite/integration/src/test/java/org/keycloak/testsuite/broker/IdentityProviderHintTest.java 5(+5 -0)
testsuite/integration/src/test/java/org/keycloak/testsuite/broker/SAMLKeyCloakServerBrokerBasicTest.java 10(+7 -3)
testsuite/integration/src/test/java/org/keycloak/testsuite/broker/SAMLKeyCloakServerBrokerWithSignatureTest.java 10(+7 -3)
Details
connections/jpa-liquibase/pom.xml 2(+1 -1)
diff --git a/connections/jpa-liquibase/pom.xml b/connections/jpa-liquibase/pom.xml
index d541d2a..659e611 100755
--- a/connections/jpa-liquibase/pom.xml
+++ b/connections/jpa-liquibase/pom.xml
@@ -21,7 +21,7 @@
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
- <artifactId>keycloak-services</artifactId>
+ <artifactId>keycloak-model-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
diff --git a/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate1_2_0_Beta1.java b/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate1_2_0_Beta1.java
index b28dce5..89e7885 100644
--- a/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate1_2_0_Beta1.java
+++ b/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate1_2_0_Beta1.java
@@ -2,7 +2,6 @@ package org.keycloak.connections.jpa.updater.liquibase.custom;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
-import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -12,11 +11,11 @@ import liquibase.statement.core.InsertStatement;
import liquibase.statement.core.UpdateStatement;
import liquibase.structure.core.Table;
import org.keycloak.Config;
+import org.keycloak.migration.MigrationProvider;
import org.keycloak.models.AdminRoles;
import org.keycloak.models.ClaimMask;
-import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.utils.KeycloakModelUtils;
-import org.keycloak.services.util.MigrationUtils;
+import org.keycloak.representations.idm.ProtocolMapperRepresentation;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@@ -296,8 +295,10 @@ public class JpaUpdate1_2_0_Beta1 extends CustomKeycloakTask {
Object acmObj = resultSet.getObject("ALLOWED_CLAIMS_MASK");
long mask = (acmObj != null) ? (Long) acmObj : ClaimMask.ALL;
- Collection<ProtocolMapperModel> protocolMappers = MigrationUtils.getMappersForClaimMask(this.kcSession, mask);
- for (ProtocolMapperModel protocolMapper : protocolMappers) {
+ MigrationProvider migrationProvider = this.kcSession.getProvider(MigrationProvider.class);
+ List<ProtocolMapperRepresentation> protocolMappers = migrationProvider.getMappersForClaimMask(mask);
+
+ for (ProtocolMapperRepresentation protocolMapper : protocolMappers) {
String mapperId = KeycloakModelUtils.generateId();
InsertStatement insert = new InsertStatement(null, null, protocolMapperTableName)
diff --git a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.Beta1.xml b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.Beta1.xml
index 9459ca3..d9d1a2e 100755
--- a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.Beta1.xml
+++ b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.Beta1.xml
@@ -152,13 +152,12 @@
<customChange class="org.keycloak.connections.jpa.updater.liquibase.custom.JpaUpdate1_2_0_Beta1"/>
- <!-- Remove obsolete 'social' stuff -->
+ <!-- Remove obsolete 'social' and 'claims' stuff -->
<dropForeignKeyConstraint baseTableName="USER_SOCIAL_LINK" constraintName="FK_68CJYS5UWM55UY823Y75XG4OM" />
- <dropPrimaryKey tableName="USER_SOCIAL_LINK" constraintName="CONSTRAINT_3" />
- <dropTable tableName="USER_SOCIAL_LINK" />
+ <dropTable tableName="USER_SOCIAL_LINK" cascadeConstraints="true" />
<dropForeignKeyConstraint baseTableName="REALM_SOCIAL_CONFIG" constraintName="FK_SV5I3C2TI7G0G922FGE683SOV" />
- <dropPrimaryKey tableName="REALM_SOCIAL_CONFIG" constraintName="CONSTRAINT_1" />
- <dropTable tableName="REALM_SOCIAL_CONFIG" />
+ <dropTable tableName="REALM_SOCIAL_CONFIG" cascadeConstraints="true" />
+ <dropColumn tableName="CLIENT" columnName="ALLOWED_CLAIMS_MASK" />
</changeSet>
</databaseChangeLog>
connections/mongo-update/pom.xml 5(+0 -5)
diff --git a/connections/mongo-update/pom.xml b/connections/mongo-update/pom.xml
index 658df45..0c67e8b 100644
--- a/connections/mongo-update/pom.xml
+++ b/connections/mongo-update/pom.xml
@@ -30,11 +30,6 @@
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>org.keycloak</groupId>
- <artifactId>keycloak-services</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<scope>provided</scope>
diff --git a/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update1_2_0_Beta1.java b/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update1_2_0_Beta1.java
index 5dcb1e7..349520a 100644
--- a/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update1_2_0_Beta1.java
+++ b/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update1_2_0_Beta1.java
@@ -1,6 +1,5 @@
package org.keycloak.connections.mongo.updater.impl.updates;
-import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -12,14 +11,11 @@ import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import org.keycloak.Config;
import org.keycloak.connections.mongo.impl.types.MapMapper;
+import org.keycloak.migration.MigrationProvider;
import org.keycloak.models.AdminRoles;
import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.utils.KeycloakModelUtils;
-import org.keycloak.protocol.LoginProtocol;
-import org.keycloak.protocol.LoginProtocolFactory;
-import org.keycloak.provider.ProviderFactory;
-import org.keycloak.services.util.MigrationUtils;
+import org.keycloak.representations.idm.ProtocolMapperRepresentation;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@@ -74,8 +70,7 @@ public class Update1_2_0_Beta1 extends Update {
DBObject identityProvider = new BasicDBObjectBuilder()
.add("internalId", KeycloakModelUtils.generateId())
.add("providerId", socialProviderId)
- .add("name", socialProviderId)
- .add("id", socialProviderId)
+ .add("alias", socialProviderId)
.add("updateProfileFirstLogin", updateProfileOnInitialSocialLogin)
.add("enabled", true)
.add("storeToken", false)
@@ -241,9 +236,10 @@ public class Update1_2_0_Beta1 extends Update {
currentClient.put("protocolMappers", dbProtocolMappers);
Object claimMask = currentClient.get("allowedClaimsMask");
- Collection<ProtocolMapperModel> clientProtocolMappers = MigrationUtils.getMappersForClaimMask(session, (Long) claimMask);
+ MigrationProvider migrationProvider = session.getProvider(MigrationProvider.class);
+ List<ProtocolMapperRepresentation> protocolMappers = migrationProvider.getMappersForClaimMask((Long) claimMask);
- for (ProtocolMapperModel protocolMapper : clientProtocolMappers) {
+ for (ProtocolMapperRepresentation protocolMapper : protocolMappers) {
BasicDBObject dbMapper = new BasicDBObject();
dbMapper.put("id", KeycloakModelUtils.generateId());
dbMapper.put("protocol", protocolMapper.getProtocol());
@@ -259,6 +255,7 @@ public class Update1_2_0_Beta1 extends Update {
dbProtocolMappers.add(dbMapper);
}
+ // Remove obsolete keys from client
currentClient.remove("allowedClaimsMask");
log.debugv("Added default mappers to application {1}", currentClient.get("name"));
diff --git a/core/src/main/java/org/keycloak/KeycloakSecurityContext.java b/core/src/main/java/org/keycloak/KeycloakSecurityContext.java
index 830a34e..ec5706f 100755
--- a/core/src/main/java/org/keycloak/KeycloakSecurityContext.java
+++ b/core/src/main/java/org/keycloak/KeycloakSecurityContext.java
@@ -50,7 +50,7 @@ public class KeycloakSecurityContext implements Serializable {
public String getRealm() {
// Assumption that issuer contains realm name
- return token.getIssuer();
+ return token.getIssuer().substring(token.getIssuer().lastIndexOf('/') + 1);
}
// SERIALIZATION
diff --git a/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
index 88c8cff..e407049 100755
--- a/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
@@ -18,6 +18,7 @@ public class ApplicationRepresentation {
protected String[] defaultRoles;
protected List<String> redirectUris;
protected List<String> webOrigins;
+ @Deprecated
protected ClaimRepresentation claims;
protected Integer notBefore;
protected Boolean bearerOnly;
diff --git a/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java
index e477be0..5f0ed4e 100755
--- a/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java
@@ -14,6 +14,7 @@ public class OAuthClientRepresentation {
protected List<String> webOrigins;
protected Boolean enabled;
protected String secret;
+ @Deprecated
protected ClaimRepresentation claims;
protected Integer notBefore;
protected Boolean publicClient;
diff --git a/core/src/main/java/org/keycloak/RSATokenVerifier.java b/core/src/main/java/org/keycloak/RSATokenVerifier.java
index da23ff9..e2f5f2b 100755
--- a/core/src/main/java/org/keycloak/RSATokenVerifier.java
+++ b/core/src/main/java/org/keycloak/RSATokenVerifier.java
@@ -12,11 +12,11 @@ import java.security.PublicKey;
* @version $Revision: 1 $
*/
public class RSATokenVerifier {
- public static AccessToken verifyToken(String tokenString, PublicKey realmKey, String realm) throws VerificationException {
- return verifyToken(tokenString, realmKey, realm, true);
+ public static AccessToken verifyToken(String tokenString, PublicKey realmKey, String realmUrl) throws VerificationException {
+ return verifyToken(tokenString, realmKey, realmUrl, true);
}
- public static AccessToken verifyToken(String tokenString, PublicKey realmKey, String realm, boolean checkActive) throws VerificationException {
+ public static AccessToken verifyToken(String tokenString, PublicKey realmKey, String realmUrl, boolean checkActive) throws VerificationException {
JWSInput input = null;
try {
input = new JWSInput(tokenString);
@@ -35,7 +35,7 @@ public class RSATokenVerifier {
if (user == null) {
throw new VerificationException("Token user was null.");
}
- if (!realm.equals(token.getIssuer())) {
+ if (!realmUrl.equals(token.getIssuer())) {
throw new VerificationException("Token audience doesn't match domain.");
}
diff --git a/core/src/test/java/org/keycloak/RSAVerifierTest.java b/core/src/test/java/org/keycloak/RSAVerifierTest.java
index cb39c6f..5382866 100755
--- a/core/src/test/java/org/keycloak/RSAVerifierTest.java
+++ b/core/src/test/java/org/keycloak/RSAVerifierTest.java
@@ -72,7 +72,7 @@ public class RSAVerifierTest {
token = new AccessToken();
token.subject("CN=Client")
- .issuer("domain")
+ .issuer("http://localhost:8080/auth/realm")
.addAccess("service").addRole("admin");
}
@@ -102,7 +102,7 @@ public class RSAVerifierTest {
}
private AccessToken verifySkeletonKeyToken(String encoded) throws VerificationException {
- return RSATokenVerifier.verifyToken(encoded, idpPair.getPublic(), "domain");
+ return RSATokenVerifier.verifyToken(encoded, idpPair.getPublic(), "http://localhost:8080/auth/realm");
}
/*
diff --git a/core/src/test/java/org/keycloak/SkeletonKeyTokenTest.java b/core/src/test/java/org/keycloak/SkeletonKeyTokenTest.java
index 268cddd..789b944 100755
--- a/core/src/test/java/org/keycloak/SkeletonKeyTokenTest.java
+++ b/core/src/test/java/org/keycloak/SkeletonKeyTokenTest.java
@@ -104,7 +104,7 @@ public class SkeletonKeyTokenTest {
private AccessToken createSimpleToken() {
AccessToken token = new AccessToken();
token.id("111");
- token.issuer("acme");
+ token.issuer("http://localhost:8080/auth/acme");
token.addAccess("foo").addRole("admin");
token.addAccess("bar").addRole("user");
return token;
diff --git a/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-connections-jpa-liquibase/main/module.xml b/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-connections-jpa-liquibase/main/module.xml
index c5b7d85..f52bc84 100755
--- a/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-connections-jpa-liquibase/main/module.xml
+++ b/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-connections-jpa-liquibase/main/module.xml
@@ -10,7 +10,6 @@
<module name="org.keycloak.keycloak-core"/>
<module name="org.keycloak.keycloak-model-api"/>
<module name="org.keycloak.keycloak-connections-jpa"/>
- <module name="org.keycloak.keycloak-services"/>
<module name="org.liquibase"/>
<module name="javax.persistence.api"/>
<module name="org.jboss.logging"/>
diff --git a/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-connections-mongo-update/main/module.xml b/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-connections-mongo-update/main/module.xml
index efc0102..c14a061 100644
--- a/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-connections-mongo-update/main/module.xml
+++ b/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-connections-mongo-update/main/module.xml
@@ -10,7 +10,6 @@
<module name="org.keycloak.keycloak-core"/>
<module name="org.keycloak.keycloak-model-api"/>
<module name="org.keycloak.keycloak-connections-mongo"/>
- <module name="org.keycloak.keycloak-services"/>
<module name="org.mongodb.mongo-java-driver"/>
<module name="org.jboss.logging"/>
<module name="javax.api"/>
diff --git a/docbook/reference/en/en-US/modules/MigrationFromOlderVersions.xml b/docbook/reference/en/en-US/modules/MigrationFromOlderVersions.xml
index 58b6b02..cbdf5d3 100755
--- a/docbook/reference/en/en-US/modules/MigrationFromOlderVersions.xml
+++ b/docbook/reference/en/en-US/modules/MigrationFromOlderVersions.xml
@@ -80,6 +80,37 @@
<section>
<title>Version specific migration</title>
<section>
+ <title>Migrating from 1.1.0.Final to 1.2.0.Beta1</title>
+ <simplesect>
+ <title>Database changed</title>
+ <para>
+ This release contains a number of changes to the database. Remember to backup your database prior to
+ upgrading.
+ </para>
+ </simplesect>
+ <simplesect>
+ <title><literal>iss</literal> in access and id tokens</title>
+ <para>
+ The value of <literal>iss</literal> claim in access and id tokens have changed from <literal>realm name</literal>
+ to <literal>realm url</literal>. This is required by OpenID Connect specification. If you're using our adapters
+ there's no change required, other than if you've been using bearer-only without specifying <literal>auth-server-url</literal>
+ you have to add it now. If you're using another library (or RSATokenVerifier) you need to make the corresponding
+ changes when verifying <literal>iss</literal>.
+ </para>
+ </simplesect>
+ <simplesect>
+ <title>OpenID Connect endpoints</title>
+ <para>
+ To comply with OpenID Connect specification the authentication and token endpoints have been changed
+ to having a single authentication endpoint and a single token endpoint. As per-spec <literal>response_type</literal>
+ and <literal>grant_type</literal> parameters are used to select the required flow. The old endpoints (<literal>/realms/{realm}/protocols/openid-connect/login</literal>,
+ <literal>/realms/{realm}/protocols/openid-connect/grants/access</literal>, <literal>/realms/{realm}/protocols/openid-connect/refresh</literal>,
+ <literal>/realms/{realm}/protocols/openid-connect/access/codes)</literal> are now deprecated and will be removed
+ in a future version.
+ </para>
+ </simplesect>
+ </section>
+ <section>
<title>Migrating from 1.1.0.Beta2 to 1.1.0.Final</title>
<itemizedlist>
<listitem>
diff --git a/examples/demo-template/database-service/src/main/webapp/WEB-INF/keycloak.json b/examples/demo-template/database-service/src/main/webapp/WEB-INF/keycloak.json
index cba5c8d..cb93854 100755
--- a/examples/demo-template/database-service/src/main/webapp/WEB-INF/keycloak.json
+++ b/examples/demo-template/database-service/src/main/webapp/WEB-INF/keycloak.json
@@ -2,6 +2,7 @@
"realm" : "demo",
"resource" : "database-service",
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+ "auth-server-url": "/auth",
"bearer-only" : true,
"ssl-required" : "external"
}
diff --git a/examples/multi-tenant/src/main/java/org/keycloak/example/multitenant/boundary/ProtectedServlet.java b/examples/multi-tenant/src/main/java/org/keycloak/example/multitenant/boundary/ProtectedServlet.java
index ff3237b..bf8212b 100755
--- a/examples/multi-tenant/src/main/java/org/keycloak/example/multitenant/boundary/ProtectedServlet.java
+++ b/examples/multi-tenant/src/main/java/org/keycloak/example/multitenant/boundary/ProtectedServlet.java
@@ -52,7 +52,7 @@ public class ProtectedServlet extends HttpServlet {
PrintWriter writer = resp.getWriter();
writer.write("Realm: ");
- writer.write(principal.getKeycloakSecurityContext().getIdToken().getIssuer());
+ writer.write(principal.getKeycloakSecurityContext().getRealm());
writer.write("<br/>User: ");
writer.write(principal.getKeycloakSecurityContext().getIdToken().getPreferredUsername());
diff --git a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java
index 8e5d445..9e68367 100755
--- a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java
+++ b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java
@@ -169,8 +169,6 @@ public class ExportUtils {
ApplicationRepresentation appRep = ModelToRepresentation.toRepresentation(app);
appRep.setSecret(app.getSecret());
- ClaimRepresentation claimRep = ModelToRepresentation.toRepresentation((ClientModel)app);
- appRep.setClaims(claimRep);
return appRep;
}
diff --git a/forms/common-themes/src/main/resources/theme/base/account/messages/messages_de.properties b/forms/common-themes/src/main/resources/theme/base/account/messages/messages_de.properties
index 36e0042..6145692 100644
--- a/forms/common-themes/src/main/resources/theme/base/account/messages/messages_de.properties
+++ b/forms/common-themes/src/main/resources/theme/base/account/messages/messages_de.properties
@@ -2,13 +2,13 @@ doLogOutAllSessions=Alle Sessionen abmelden
doSave=Speichern
doCancel=Abbrechen
doRemove=Entfernen
-doAdd=Hinzuf�gen
+doAdd=Hinzuf\u00FCgen
doSignOut=Abmelden
editAccountHtmlTtile=Benutzerkonto Bearbeiten
federatedIdentitiesHtmlTitle=Federated Identities
accountLogHtmlTitle=Benutzerkonto Log
-changePasswordHtmlTitle=Passwort �ndern
+changePasswordHtmlTitle=Passwort \u00C4ndern
sessionsHtmlTitle=Sessions
accountManagementTitle=Keycloak Benutzerkontoverwaltung
authenticatorTitle=Authenticator
@@ -18,7 +18,7 @@ email=E-Mail
firstName=Vorname
lastName=Nachname
password=Passwort
-passwordConfirm=Passwortbest�tigung
+passwordConfirm=Passwortbest\u00E4tigung
passwordNew=Neues Passwort
username=Benutzernamen
street=Strasse
@@ -30,8 +30,8 @@ country=Land
requiredFields=Erforderliche Felder
allFieldsRequired=Alle Felder sind Erforderlich
-backToApplication=« Zur�ck zur Applikation
-backTo=Zur�ck zu {0}
+backToApplication=« Zur\u00FCck zur Applikation
+backTo=Zur\u00FCck zu {0}
date=Datum
event=Ereignis
@@ -53,7 +53,7 @@ log=Log
configureAuthenticators=Authenticators konfigurieren
mobile=Mobile
totpStep1=Installieren Sie <a href="https://fedorahosted.org/freeotp/" target="_blank">FreeOTP</a> oder <a href="http://code.google.com/p/google-authenticator/" target="_blank">Google Authenticator</a> auf Ihrem Smartphone.
-totpStep2=�ffnen Sie die Applikation und scannen Sie den Barcode oder geben sie den Code ein.
+totpStep2=\u00D6ffnen Sie die Applikation und scannen Sie den Barcode oder geben sie den Code ein.
totpStep3=Geben Sie den One-time Code welcher die Applikation generiert hat ein und klicken Sie auf Speichern.
@@ -61,16 +61,16 @@ missingFirstNameMessage=Bitte geben Sie einen Vornamen ein.
missingEmailMessage=Bitte geben Sie eine E-Mail Adresse ein.
missingLastNameMessage=Bitte geben Sie einen Nachnamen ein.
missingPasswordMessage=Bitte geben Sie ein Passwort ein.
-notMatchPasswordMessage=Passw�rter sind nicht identisch.
+notMatchPasswordMessage=Passw\u00F6rter sind nicht identisch.
missingTotpMessage=Bitte geben Sie den One-time Code ein.
-invalidPasswordExistingMessage=Das aktuelle Passwort is ung�ltig.
-invalidPasswordConfirmMessage=Die Passwortbest�tigung ist nicht identisch.
-invalidTotpMessage=Ung�ltiger One-time Code.
-invalidEmailMessage=Ung�ltige E-Mail Adresse.
+invalidPasswordExistingMessage=Das aktuelle Passwort is ung\u00FCltig.
+invalidPasswordConfirmMessage=Die Passwortbest\u00E4tigung ist nicht identisch.
+invalidTotpMessage=Ung\u00FCltiger One-time Code.
+invalidEmailMessage=Ung\u00FCltige E-Mail Adresse.
-readOnlyUserMessage=Sie k�nnen dieses Benutzerkonto nicht �ndern, da es schreibgesch�tzt ist.
-readOnlyPasswordMessage=Sie k�nnen dieses Passwort nicht �ndern, da es schreibgesch�tzt ist.
+readOnlyUserMessage=Sie k\u00F6nnen dieses Benutzerkonto nicht \u00E4ndern, da es schreibgesch\u00FCtzt ist.
+readOnlyPasswordMessage=Sie k\u00F6nnen dieses Passwort nicht \u00E4ndern, da es schreibgesch\u00FCtzt ist.
successTotpMessage=Mobile Authentifizierung eingerichtet.
successTotpRemovedMessage=Mobile Authentifizierung entfernt.
@@ -79,23 +79,23 @@ accountUpdatedMessage=Ihr Benutzerkonto wurde aktualisiert.
accountPasswordUpdatedMessage=Ihr Passwort wurde aktualisiert.
missingIdentityProviderMessage=Identity Provider nicht angegeben.
-invalidFederatedIdentityActionMessage=Ung�ltige oder fehlende Aktion.
+invalidFederatedIdentityActionMessage=Ung\u00FCltige oder fehlende Aktion.
identityProviderNotFoundMessage=Angegebener Identity Provider nicht gefunden.
-federatedIdentityLinkNotActiveMessage=Diese Identit�t ist nicht mehr aktiv.
-federatedIdentityRemovingLastProviderMessage=Sie k�nnen den letzen Eintrag nicht entfernen, da Sie kein Passwort haben.
+federatedIdentityLinkNotActiveMessage=Diese Identit\u00E4t ist nicht mehr aktiv.
+federatedIdentityRemovingLastProviderMessage=Sie k\u00F6nnen den letzen Eintrag nicht entfernen, da Sie kein Passwort haben.
identityProviderRedirectErrorMessage=Fehler bei der Weiterleitung zum Identity Provider.
identityProviderRemovedMessage=Identity Provider erfolgreich entfernt.
accountDisabledMessage=Benutzerkonto ist gesperrt, bitte kontaktieren Sie den Admin.
-accountTemporarilyDisabledMessage=Benutzerkonto ist tempor�r gesperrt, bitte kontaktieren Sie den Admin oder versuchen Sie es sp�ter noch einmal.
-invalidPasswordMinLengthMessage=Ung�ltiges Passwort: minimum l�nge {0}.
-invalidPasswordMinDigitsMessage=Ung�ltiges Passwort: muss mindestens {0} Zahl(en) beinhalten.
-invalidPasswordMinLowerCaseCharsMessage=Ung�ltiges Passwort: muss mindestens {0} Kleinbuchstaben beinhalten.
-invalidPasswordMinUpperCaseCharsMessage=Ung�ltiges Passwort: muss mindestens {0} Grossbuchstaben beinhalten.
-invalidPasswordMinSpecialCharsMessage=Ung�ltiges Passwort\: muss mindestens {0} Spezialzeichen beinhalten.
-invalidPasswordNotUsernameMessage=Ung�ltiges Passwort\: darf nicht gleich sein wie Benutzername.
+accountTemporarilyDisabledMessage=Benutzerkonto ist tempor\u00E4r gesperrt, bitte kontaktieren Sie den Admin oder versuchen Sie es sp\u00E4ter noch einmal.
+invalidPasswordMinLengthMessage=Ung\u00FCltiges Passwort: minimum l\u00E4nge {0}.
+invalidPasswordMinDigitsMessage=Ung\u00FCltiges Passwort: muss mindestens {0} Zahl(en) beinhalten.
+invalidPasswordMinLowerCaseCharsMessage=Ung\u00FCltiges Passwort: muss mindestens {0} Kleinbuchstaben beinhalten.
+invalidPasswordMinUpperCaseCharsMessage=Ung\u00FCltiges Passwort: muss mindestens {0} Grossbuchstaben beinhalten.
+invalidPasswordMinSpecialCharsMessage=Ung\u00FCltiges Passwort\: muss mindestens {0} Spezialzeichen beinhalten.
+invalidPasswordNotUsernameMessage=Ung\u00FCltiges Passwort\: darf nicht gleich sein wie Benutzername.
locale_de=Deutsch
locale_en=Englisch
-locale_pt-BR=Portugu\u00eas (Brasil)
\ No newline at end of file
+locale_pt-BR=Portugu\u00EAs (Brasil)
\ No newline at end of file
diff --git a/forms/common-themes/src/main/resources/theme/base/account/messages/messages_en.properties b/forms/common-themes/src/main/resources/theme/base/account/messages/messages_en.properties
index d0f5b71..48a51aa 100755
--- a/forms/common-themes/src/main/resources/theme/base/account/messages/messages_en.properties
+++ b/forms/common-themes/src/main/resources/theme/base/account/messages/messages_en.properties
@@ -97,4 +97,4 @@ invalidPasswordNotUsernameMessage=Invalid password\: must not be equal to the us
locale_de=German
locale_en=English
-locale_pt-BR=Portugu\u00eas (Brasil)
\ No newline at end of file
+locale_pt-BR=Portugu\u00EAs (Brasil)
\ No newline at end of file
diff --git a/forms/common-themes/src/main/resources/theme/base/account/messages/messages_pt_BR.properties b/forms/common-themes/src/main/resources/theme/base/account/messages/messages_pt_BR.properties
index 20952a9..bf3144e 100644
--- a/forms/common-themes/src/main/resources/theme/base/account/messages/messages_pt_BR.properties
+++ b/forms/common-themes/src/main/resources/theme/base/account/messages/messages_pt_BR.properties
@@ -1,31 +1,31 @@
-authenticatorCode=C\u00f3digo autenticador
+authenticatorCode=C\u00F3digo autenticador
email=Email
firstName=Primeiro nome
lastName=Sobrenome
password=Senha
-passwordConfirm=Confirma\u00e7\u00e3o
+passwordConfirm=Confirma\u00E7\u00E3o
passwordNew=Nova senha
-username=Nome de us\u00faario
+username=Nome de us\u00FAario
street=Logradouro
locality=Cidade ou Localidade
region=Estado
postal_code=CEP
-country=Pa\u00eds
+country=Pa\u00EDs
missingFirstNameMessage=Por favor, informe o primeiro nome.
-invalidEmailMessage=E-mail inv\u00e1lido.
+invalidEmailMessage=E-mail inv\u00E1lido.
missingLastNameMessage=Por favor, informe o sobrenome.
missingEmailMessage=Por favor, informe o e-mail.
missingPasswordMessage=Por favor, informe a senha.
-notMatchPasswordMessage=As senhas n\u00e3o coincidem.
+notMatchPasswordMessage=As senhas n\u00E3o coincidem.
-missingTotpMessage=Por favor, informe o c\u00f3digo autenticador.
-invalidPasswordExistingMessage=Senha atual inv\u00e1lida.
-invalidPasswordConfirmMessage=A senha de confirma\u00e7\u00e3o n\u00e3o coincide.
-invalidTotpMessage=C\u00f3digo autenticador inv\u00e1lido.
+missingTotpMessage=Por favor, informe o c\u00F3digo autenticador.
+invalidPasswordExistingMessage=Senha atual inv\u00E1lida.
+invalidPasswordConfirmMessage=A senha de confirma\u00E7\u00E3o n\u00E3o coincide.
+invalidTotpMessage=C\u00F3digo autenticador inv\u00E1lido.
-readOnlyUserMessage=Voc\u00ea n\u00e3o pode atualizar sua conta, uma vez que \u00e9 apenas de leitura
-readOnlyPasswordMessage=Voc\u00ea n\u00e3o pode atualizar sua senha, sua conta \u00e9 somente leitura
+readOnlyUserMessage=Voc\u00EA n\u00E3o pode atualizar sua conta, uma vez que \u00E9 apenas de leitura
+readOnlyPasswordMessage=Voc\u00EA n\u00E3o pode atualizar sua senha, sua conta \u00E9 somente leitura
successTotpMessage=Autenticador mobile configurado.
successTotpRemovedMessage=Autenticador mobile removido.
@@ -33,26 +33,26 @@ successTotpRemovedMessage=Autenticador mobile removido.
accountUpdatedMessage=Sua conta foi atualizada
accountPasswordUpdatedMessage=Sua senha foi atualizada
-missingIdentityProviderMessage=Provedor de identidade n\u00e3o especificado
-invalidFederatedIdentityActionMessage=A\u00e7\u00e3o inv\u00e1lida ou ausente
-identityProviderNotFoundMessage=O provedor de identidade especificado n\u00e3o foi encontrado
-federatedIdentityLinkNotActiveMessage=Esta identidade n\u00e3o est\u00e1 mais em atividade
-federatedIdentityRemovingLastProviderMessage=Voc\u00ea n\u00e3o pode remover a \u00faltima identidade federada como voc\u00ea n\u00e3o tem senha
+missingIdentityProviderMessage=Provedor de identidade n\u00E3o especificado
+invalidFederatedIdentityActionMessage=A\u00E7\u00E3o inv\u00E1lida ou ausente
+identityProviderNotFoundMessage=O provedor de identidade especificado n\u00E3o foi encontrado
+federatedIdentityLinkNotActiveMessage=Esta identidade n\u00E3o est\u00E1 mais em atividade
+federatedIdentityRemovingLastProviderMessage=Voc\u00EA n\u00E3o pode remover a \u00FAltima identidade federada como voc\u00EA n\u00E3o tem senha
identityProviderRedirectErrorMessage=Falha ao redirecionar para o provedor de identidade
identityProviderRemovedMessage=Provedor de identidade removido com sucesso
accountDisabledMessage=Conta desativada, contate administrador
-doLogOutAllSessions=Sair de todas sess\u00f5es
+doLogOutAllSessions=Sair de todas sess\u00F5es
-accountTemporarilyDisabledMessage=A conta est\u00e1 temporariamente indispon\u00edvel, contate administrador ou tente novamente mais tarde
-invalidPasswordMinLengthMessage=Senha inv\u00e1lida: comprimento m\u00ednimo {0}
-invalidPasswordMinLowerCaseCharsMessage=Senha inv\u00e1lida: deve conter pelo menos {0} caracteres min\u00fasculos
-invalidPasswordMinDigitsMessage=Senha inv\u00e1lida: deve conter pelo menos {0} d\u00edgitos num\u00e9ricos
-invalidPasswordMinUpperCaseCharsMessage=Senha inv\u00e1lida: deve conter pelo menos {0} caracteres mai\u00fasculos
-invalidPasswordMinSpecialCharsMessage=Senha inv\u00e1lida: deve conter pelo menos {0} caracteres especiais
-invalidPasswordNotUsernameMessage=Senha inv\u00e1lida\: n\u00e3o deve ser igual ao nome de usu\u00e1rio
+accountTemporarilyDisabledMessage=A conta est\u00E1 temporariamente indispon\u00EDvel, contate administrador ou tente novamente mais tarde
+invalidPasswordMinLengthMessage=Senha inv\u00E1lida: comprimento m\u00EDnimo {0}
+invalidPasswordMinLowerCaseCharsMessage=Senha inv\u00E1lida: deve conter pelo menos {0} caracteres min\u00FAsculos
+invalidPasswordMinDigitsMessage=Senha inv\u00E1lida: deve conter pelo menos {0} d\u00EDgitos num\u00E9ricos
+invalidPasswordMinUpperCaseCharsMessage=Senha inv\u00E1lida: deve conter pelo menos {0} caracteres mai\u00FAsculos
+invalidPasswordMinSpecialCharsMessage=Senha inv\u00E1lida: deve conter pelo menos {0} caracteres especiais
+invalidPasswordNotUsernameMessage=Senha inv\u00E1lida\: n\u00E3o deve ser igual ao nome de usu\u00E1rio
locale_de=Deutsch
locale_en=English
-locale_pt-BR=Portugu\u00eas (BR)
+locale_pt-BR=Portugu\u00EAs (BR)
diff --git a/forms/common-themes/src/main/resources/theme/base/login/messages/messages_de.properties b/forms/common-themes/src/main/resources/theme/base/login/messages/messages_de.properties
index 62f88da..1b570c7 100644
--- a/forms/common-themes/src/main/resources/theme/base/login/messages/messages_de.properties
+++ b/forms/common-themes/src/main/resources/theme/base/login/messages/messages_de.properties
@@ -11,12 +11,12 @@ registerWithTitle=Registrierung bei {0}
registerWithTitleHtml=Registrierung bei <strong>{0}</strong>
loginTitle=Anmeldung bei {0}
loginTitleHtml=Anmeldung bei <strong>{0}</strong>
-loginOauthTitle=Tempor�rer zugriff auf {0}
-loginOauthTitleHtml=Tempor�rer zugriff auf <strong>{0}</strong> angefordert von <strong>{1}</strong>.
+loginOauthTitle=Tempor\u00E4rer zugriff auf {0}
+loginOauthTitleHtml=Tempor\u00E4rer zugriff auf <strong>{0}</strong> angefordert von <strong>{1}</strong>.
loginTotpTitle=Mobile Authentifizierung Einrichten
loginProfileTitle=Benutzerkonto Informationen aktualisieren
-oauthGrantTitle=OAuth gew�hren
-oauthGrantTitleHtml=Tempor�rer zugriff auf <strong>{0}</strong> angefordert von <strong>{1}</strong>.
+oauthGrantTitle=OAuth gew\u00E4hren
+oauthGrantTitleHtml=Tempor\u00E4rer zugriff auf <strong>{0}</strong> angefordert von <strong>{1}</strong>.
errorTitle=Es tut uns leid...
errorTitleHtml=Es tut uns leid...
emailVerifyTitle=E-Mail verifizieren
@@ -33,9 +33,9 @@ fullName=Name
lastName=Nachname
email=E-Mail
password=Passwort
-passwordConfirm=Passwort best�tigen
+passwordConfirm=Passwort best\u00E4tigen
passwordNew=Neues Passwort
-passwordNewConfirm=Neues Passwort best�tigen
+passwordNewConfirm=Neues Passwort best\u00E4tigen
rememberMe=Angemeldet bleiben
authenticatorCode=One-time Code
street=Strasse
@@ -45,31 +45,31 @@ locality=Stadt oder Ortschaft
country=Land
loginTotpStep1=Installieren Sie <a href="https://fedorahosted.org/freeotp/" target="_blank">FreeOTP</a> oder <a href="http://code.google.com/p/google-authenticator/" target="_blank">Google Authenticator</a> auf Ihrem Smartphone.
-loginTotpStep2=�ffnen Sie die Applikation und scannen Sie den Barcode oder geben sie den Code ein.
+loginTotpStep2=\u00D6ffnen Sie die Applikation und scannen Sie den Barcode oder geben sie den Code ein.
loginTotpStep3=Geben Sie den One-time Code welcher die Applikation generiert hat ein und klicken Sie auf Absenden.
loginTotpOneTime=One-time Code
-oauthGrantRequest=Wollen Sie diese Zugriffsreche gew�hren?
+oauthGrantRequest=Wollen Sie diese Zugriffsreche gew\u00E4hren?
inResource=in <strong>{0}</strong>
emailVerifyInstruction1=Ein E-Mail mit weitern Anweisungen wurde an Sie versendet.
-emailVerifyInstruction2=Falls Sie kein E-Mail erhalten haben, dann k�nnen Sie
+emailVerifyInstruction2=Falls Sie kein E-Mail erhalten haben, dann k\u00F6nnen Sie
emailVerifyInstruction3=um ein neues E-Mail zu verschicken.
-backToLogin=« Zur�ck zur Anmeldung
-backToApplication=« Zur�ck zur Applikation
+backToLogin=« Zur\u00FCck zur Anmeldung
+backToApplication=« Zur\u00FCck zur Applikation
emailInstruction=Geben Sie ihren Benutzernamen oder E-Mail Adresse ein und klicken Sie auf Absenden. Danach werden wir ihnen ein E-Mail mit weiteren Instruktionen zusenden.
-copyCodeInstruction=Bitte kopieren sie den folgenden Code und f�gen ihn in die Applikation ein\:
+copyCodeInstruction=Bitte kopieren sie den folgenden Code und f\u00FCgen ihn in die Applikation ein\:
-personalInfo=Pers�nliche Informationen:
+personalInfo=Pers\u00F6nliche Informationen:
-invalidUserMessage=Ung�ltiger Benutzername oder Passwort.
-invalidEmailMessage=Ung�ltige E-Mail Adresse.
+invalidUserMessage=Ung\u00FCltiger Benutzername oder Passwort.
+invalidEmailMessage=Ung\u00FCltige E-Mail Adresse.
accountDisabledMessage=Benutzerkonto ist gesperrt, bitte kontaktieren Sie den Admin.
-accountTemporarilyDisabledMessage=Benutzerkonto ist tempor�r gesperrt, bitte kontaktieren Sie den Admin oder versuchen Sie es sp�ter noch einmal.
-expiredCodeMessage=Zeit�berschreitung bei der Anmeldung. Bitter melden Sie sich erneut an.
+accountTemporarilyDisabledMessage=Benutzerkonto ist tempor\u00E4r gesperrt, bitte kontaktieren Sie den Admin oder versuchen Sie es sp\u00E4ter noch einmal.
+expiredCodeMessage=Zeit\u00FCberschreitung bei der Anmeldung. Bitter melden Sie sich erneut an.
missingFirstNameMessage=Bitte geben Sie einen Vornamen ein.
missingLastNameMessage=Bitte geben Sie einen Nachnamen ein.
@@ -77,70 +77,70 @@ missingEmailMessage=Bitte geben Sie eine E-Mail Adresse ein.
missingUsernameMessage=Bitte geben Sie einen Benutzernamen ein.
missingPasswordMessage=Bitte geben Sie ein Passwort ein.
missingTotpMessage=Bitte geben Sie den One-time Code ein.
-notMatchPasswordMessage=Passw�rter sind nicht identisch.
+notMatchPasswordMessage=Passw\u00F6rter sind nicht identisch.
-invalidPasswordExistingMessage=Das aktuelle Passwort is ung�ltig.
-invalidPasswordConfirmMessage=Die Passwortbest�tigung ist nicht identisch.
-invalidTotpMessage=Ung�ltiger One-time Code.
+invalidPasswordExistingMessage=Das aktuelle Passwort is ung\u00FCltig.
+invalidPasswordConfirmMessage=Die Passwortbest\u00E4tigung ist nicht identisch.
+invalidTotpMessage=Ung\u00FCltiger One-time Code.
usernameExistsMessage=Benutzername existiert bereits.
emailExistsMessage=E-Mail existiert bereits.
-federatedIdentityEmailExistsMessage=Es existiert bereits ein Benutzer mit dieser E-Mail Adresse. Bitte melden Sie sich bei der Benutzerverwaltung an um das Benutzerkonto zu verkn�pfen.
-federatedIdentityUsernameExistsMessage=Es existiert bereits ein Benutzer mit diesem Benutzernamen. Bitte melden Sie sich bei der Benutzerverwaltung an um das Benutzerkonto zu verkn�pfen.
+federatedIdentityEmailExistsMessage=Es existiert bereits ein Benutzer mit dieser E-Mail Adresse. Bitte melden Sie sich bei der Benutzerverwaltung an um das Benutzerkonto zu verkn\u00FCpfen.
+federatedIdentityUsernameExistsMessage=Es existiert bereits ein Benutzer mit diesem Benutzernamen. Bitte melden Sie sich bei der Benutzerverwaltung an um das Benutzerkonto zu verkn\u00FCpfen.
-configureTotpMessage=Sie m�ssen eine Mobile Authentifizierung einrichten um das Benutzerkonto zu aktivieren.
-updateProfileMessage=Sie m�ssen ihr Benutzerkonto aktualisieren um das Benutzerkonto zu aktivieren.
-updatePasswordMessage=Sie m�ssen ihr Passwort �ndern um das Benutzerkonto zu aktivieren.
-verifyEmailMessage=Sie m�ssen ihre E-Mail Adresse verifizieren um das Benutzerkonto zu aktivieren.
+configureTotpMessage=Sie m\u00FCssen eine Mobile Authentifizierung einrichten um das Benutzerkonto zu aktivieren.
+updateProfileMessage=Sie m\u00FCssen ihr Benutzerkonto aktualisieren um das Benutzerkonto zu aktivieren.
+updatePasswordMessage=Sie m\u00FCssen ihr Passwort \u00E4ndern um das Benutzerkonto zu aktivieren.
+verifyEmailMessage=Sie m\u00FCssen ihre E-Mail Adresse verifizieren um das Benutzerkonto zu aktivieren.
-emailSentMessage=Sie sollten in k�rze ein E-Mail mit weiteren Instruktionen erhalten.
-emailSendErrorMessage=Das E-Mail konnte nicht versendet werden, bitte versuchen Sie es sp�ter nochmals.
+emailSentMessage=Sie sollten in k\u00FCrze ein E-Mail mit weiteren Instruktionen erhalten.
+emailSendErrorMessage=Das E-Mail konnte nicht versendet werden, bitte versuchen Sie es sp\u00E4ter nochmals.
accountUpdatedMessage=Ihr Benutzerkonto wurde aktualisiert.
accountPasswordUpdatedMessage=Ihr Passwort wurde aktualisiert.
noAccessMessage=Kein Zugriff
-invalidPasswordMinLengthMessage=Ung�ltiges Passwort: minimum l�nge {0}.
-invalidPasswordMinDigitsMessage=Ung�ltiges Passwort: muss mindestens {0} Zahl(en) beinhalten.
-invalidPasswordMinLowerCaseCharsMessage=Ung�ltiges Passwort: muss mindestens {0} Kleinbuchstaben beinhalten.
-invalidPasswordMinUpperCaseCharsMessage=Ung�ltiges Passwort: muss mindestens {0} Grossbuchstaben beinhalten.
-invalidPasswordMinSpecialCharsMessage=Ung�ltiges Passwort: muss mindestens {0} Spezialzeichen beinhalten.
-invalidPasswordNotUsernameMessage=Ung�ltiges Passwort\: darf nicht gleich sein wie Benutzername.
+invalidPasswordMinLengthMessage=Ung\u00FCltiges Passwort: minimum l\u00E4nge {0}.
+invalidPasswordMinDigitsMessage=Ung\u00FCltiges Passwort: muss mindestens {0} Zahl(en) beinhalten.
+invalidPasswordMinLowerCaseCharsMessage=Ung\u00FCltiges Passwort: muss mindestens {0} Kleinbuchstaben beinhalten.
+invalidPasswordMinUpperCaseCharsMessage=Ung\u00FCltiges Passwort: muss mindestens {0} Grossbuchstaben beinhalten.
+invalidPasswordMinSpecialCharsMessage=Ung\u00FCltiges Passwort: muss mindestens {0} Spezialzeichen beinhalten.
+invalidPasswordNotUsernameMessage=Ung\u00FCltiges Passwort\: darf nicht gleich sein wie Benutzername.
failedToProcessResponseMessage=Konnte Response nicht verarbeiten.
httpsRequiredMessage=HTTPS erforderlich.
realmNotEnabledMessage=Realm nicht aktiviert.
-invalidRequestMessage=Ung�ltiger Request.
-unknownLoginRequesterMessage=Ung�ltiger login requester
+invalidRequestMessage=Ung\u00FCltiger Request.
+unknownLoginRequesterMessage=Ung\u00FCltiger login requester
loginRequesterNotEnabledMessage=Login requester nicht aktiviert.
-bearerOnlyMessage=Bearer-only Applikationen k�nne sich nicht via Browser anmelden.
-directGrantsOnlyMessage=Direct-grants-only Clients k�nne sich nicht via Browser anmelden.
-invalidRedirectUriMessage=Ung�ltige redirect uri.
-unsupportedNameIdFormatMessage=Nicht unterst�tztes NameIDFormat.
-invlidRequesterMessage=Ung�ltiger requester.
+bearerOnlyMessage=Bearer-only Applikationen k\u00F6nne sich nicht via Browser anmelden.
+directGrantsOnlyMessage=Direct-grants-only Clients k\u00F6nne sich nicht via Browser anmelden.
+invalidRedirectUriMessage=Ung\u00FCltige redirect uri.
+unsupportedNameIdFormatMessage=Nicht unterst\u00FCtztes NameIDFormat.
+invlidRequesterMessage=Ung\u00FCltiger requester.
registrationNotAllowedMessage=Registrierung nicht erlaubt.
-permissionNotApprovedMessage=Berechtigung nicht best�tigt.
+permissionNotApprovedMessage=Berechtigung nicht best\u00E4tigt.
noRelayStateInResponseMessage=Kein relay state in der Antwort von dem Identity Provider [{0}].
-identityProviderAlreadyLinkedMessage=Die Identit�t welche von dem Identity Provider [{0}] zur�ckgegeben wurde, ist bereits mit einem anderen Benutzer verkn�pft.
-insufficientPermissionMessage=Nicht gen�gend Rechte um die Identit�t zu verkn�pfen.
+identityProviderAlreadyLinkedMessage=Die Identit\u00E4t welche von dem Identity Provider [{0}] zur\u00FCckgegeben wurde, ist bereits mit einem anderen Benutzer verkn\u00FCpft.
+insufficientPermissionMessage=Nicht gen\u00FCgend Rechte um die Identit\u00E4t zu verkn\u00FCpfen.
couldNotProceedWithAuthenticationRequestMessage=Konnte den Authentifizierungs Request nicht weiter verarbeiten.
couldNotObtainTokenMessage=Konnte kein token vom Identity Provider [{0}] entnehmen.
-unexpectedErrorRetrievingTokenMessage=Unerwarteter Fehler w�hrend dem Empfang des Token von dem Identity Provider [{0}].
-unexpectedErrorHandlingResponseMessage=Unerwarteter Fehler w�hrend der Bearbeitung des Respons vom Identity Provider [{0}].
+unexpectedErrorRetrievingTokenMessage=Unerwarteter Fehler w\u00E4hrend dem Empfang des Token von dem Identity Provider [{0}].
+unexpectedErrorHandlingResponseMessage=Unerwarteter Fehler w\u00E4hrend der Bearbeitung des Respons vom Identity Provider [{0}].
identityProviderAuthenticationFailedMessage=Authentifizierung Fehlgeschlagen. Konnte sich mit dem Identity Provider [{0}] nicht authentifizieren.
couldNotSendAuthenticationRequestMessage=Konnte Authentifizierungs Request nicht an den Identity Provider [{0}] schicken.
-unexpectedErrorHandlingRequestMessage=Unerwarteter Fehler w�hrend der Bearbeitung des Requests zum Identity Provider [{0}].
-invalidAccessCodeMessage=Ung�ltiger Access-Code.
+unexpectedErrorHandlingRequestMessage=Unerwarteter Fehler w\u00E4hrend der Bearbeitung des Requests zum Identity Provider [{0}].
+invalidAccessCodeMessage=Ung\u00FCltiger Access-Code.
sessionNotActiveMessage=Session nicht aktiv.
-unknownCodeMessage=Unbekannter Code, bitte melden Sie sich erneut �ber die Applikation an.
-invalidCodeMessage=Ung�ltiger Code, bitte melden Sie sich erneut �ber die Applikation an.
-identityProviderUnexpectedErrorMessage=Unerwarteter Fehler w�hrend der Authentifizierung mit dem Identity Provider.
-identityProviderNotFoundMessage=Konnte kein Identity Provider mit der Identit�t [{0}] finden.
-realmSupportsNoCredentialsMessage=Realm [{0}] unterst�tzt keine Credential Typen.
-identityProviderNotUniqueMessage=Realm [{0}] unterst�tz mehrere Identity Providers.
+unknownCodeMessage=Unbekannter Code, bitte melden Sie sich erneut \u00FCber die Applikation an.
+invalidCodeMessage=Ung\u00FCltiger Code, bitte melden Sie sich erneut \u00FCber die Applikation an.
+identityProviderUnexpectedErrorMessage=Unerwarteter Fehler w\u00E4hrend der Authentifizierung mit dem Identity Provider.
+identityProviderNotFoundMessage=Konnte kein Identity Provider mit der Identit\u00E4t [{0}] finden.
+realmSupportsNoCredentialsMessage=Realm [{0}] unterst\u00FCtzt keine Credential Typen.
+identityProviderNotUniqueMessage=Realm [{0}] unterst\u00FCtz mehrere Identity Providers.
invalidParameterMessage=Invalid parameter\: {0}
missingParameterMessage=Missing parameter\: {0}
@@ -150,4 +150,4 @@ emailVerifiedMessage=Ihr E-Mail Adresse wurde erfolgreich verifiziert.
locale_de=Deutsch
locale_en=Englisch
-locale_pt-BR=Portugu\u00eas (Brasil)
\ No newline at end of file
+locale_pt-BR=Portugu\u00EAs (Brasil)
\ No newline at end of file
diff --git a/forms/common-themes/src/main/resources/theme/base/login/messages/messages_en.properties b/forms/common-themes/src/main/resources/theme/base/login/messages/messages_en.properties
index 0a636e4..84f32c7 100755
--- a/forms/common-themes/src/main/resources/theme/base/login/messages/messages_en.properties
+++ b/forms/common-themes/src/main/resources/theme/base/login/messages/messages_en.properties
@@ -144,7 +144,7 @@ emailVerifiedMessage=Your email address has been verified.
locale_de=German
locale_en=English
-locale_pt-BR=Portugu\u00eas (Brasil)
+locale_pt-BR=Portugu\u00EAs (Brasil)
backToApplication=« Back to Application
missingParameterMessage=Missing parameters\: {0}
diff --git a/forms/common-themes/src/main/resources/theme/base/login/messages/messages_pt_BR.properties b/forms/common-themes/src/main/resources/theme/base/login/messages/messages_pt_BR.properties
index 0cf47cb..497c0c2 100644
--- a/forms/common-themes/src/main/resources/theme/base/login/messages/messages_pt_BR.properties
+++ b/forms/common-themes/src/main/resources/theme/base/login/messages/messages_pt_BR.properties
@@ -3,7 +3,7 @@ doRegister=Cadastre-se
doCancel=Cancelar
doSubmit=Ok
doYes=Sim
-doNo=N\u00e3o
+doNo=N\u00E3o
doForgotPassword=Esqueceu sua senha?
doClickHere=Clique aqui
@@ -11,21 +11,21 @@ registerWithTitle=Registre-se com {0}
registerWithTitleHtml=Registre-se com <strong>{0}</strong>
loginTitle=Entrar em {0}
loginTitleHtml=Entrar em <strong>{0}</strong>
-loginOauthTitle=Acesso tempor\u00e1rio para {0}
-loginOauthTitleHtml=Acesso tempor\u00e1rio para <strong>{0}<strong> solicitado por <strong>{1}</strong>.
-loginTotpTitle=Configura\u00e7\u00e3o do autenticador mobile
-loginProfileTitle=Atualiza\u00e7\u00e3o de Informa\u00e7\u00f5es da Conta
-oauthGrantTitle=Concess\u00e3o OAuth
-oauthGrantTitleHtml=Acesso tempor\u00e1rio para <strong>{0}</strong> solicitado pela <strong>{1}</strong>.
-errorTitle=N\u00f3s lamentamos...
-errorTitleHtml=N\u00f3s <strong>lamentamos</strong> ...
-emailVerifyTitle=Verifica\u00e7\u00e3o de e-mail
+loginOauthTitle=Acesso tempor\u00E1rio para {0}
+loginOauthTitleHtml=Acesso tempor\u00E1rio para <strong>{0}<strong> solicitado por <strong>{1}</strong>.
+loginTotpTitle=Configura\u00E7\u00E3o do autenticador mobile
+loginProfileTitle=Atualiza\u00E7\u00E3o de Informa\u00E7\u00F5es da Conta
+oauthGrantTitle=Concess\u00E3o OAuth
+oauthGrantTitleHtml=Acesso tempor\u00E1rio para <strong>{0}</strong> solicitado pela <strong>{1}</strong>.
+errorTitle=N\u00F3s lamentamos...
+errorTitleHtml=N\u00F3s <strong>lamentamos</strong> ...
+emailVerifyTitle=Verifica\u00E7\u00E3o de e-mail
emailForgotTitle=Esqueceu sua senha?
-updatePasswordTitle=Atualiza\u00e7\u00e3o de senha
+updatePasswordTitle=Atualiza\u00E7\u00E3o de senha
-noAccount=Novo usu\u00e1rio?
-username=Nome de usu\u00e1rio
-usernameOrEmail=Nome de usu\u00e1rio ou email
+noAccount=Novo usu\u00E1rio?
+username=Nome de usu\u00E1rio
+usernameOrEmail=Nome de usu\u00E1rio ou email
firstName=Primeiro nome
fullName=Nome completo
lastName=Sobrenome
@@ -33,60 +33,60 @@ email=Email
password=Senha
passwordConfirm=Confirme a senha
passwordNew=Nova senha
-passwordNewConfirm=Confirma\u00e7\u00e3o da nova senha
+passwordNewConfirm=Confirma\u00E7\u00E3o da nova senha
rememberMe=Relembre-me
-authenticatorCode=C\u00f3digo autenticador
+authenticatorCode=C\u00F3digo autenticador
street=Logradouro
locality=Cidade ou localidade
region=Estado
postal_code=CEP
-country=Pa\u00eds
+country=Pa\u00EDs
loginTotpStep1=Instale <a href="https://fedorahosted.org/freeotp/" target="_blank">FreeOTP</a> ou <a href="http://code.google.com/p/google-authenticator/" target="_blank">Google Authenticator</a> em seu celular
-loginTotpStep2=Abra o aplicativo e escanei o c\u00f3digo de barras ou digite o c\u00f3digo
-loginTotpStep3=Digite o c\u00f3digo autenticador fornecido pelo aplicativo e clique em Enviar para concluir a configura\u00e7\u00e3o
-loginTotpOneTime=C\u00f3digo autenticador
+loginTotpStep2=Abra o aplicativo e escanei o c\u00F3digo de barras ou digite o c\u00F3digo
+loginTotpStep3=Digite o c\u00F3digo autenticador fornecido pelo aplicativo e clique em Enviar para concluir a configura\u00E7\u00E3o
+loginTotpOneTime=C\u00F3digo autenticador
-oauthGrantRequest=Voc\u00ea concede esses privil\u00e9gios de acesso?
+oauthGrantRequest=Voc\u00EA concede esses privil\u00E9gios de acesso?
-emailVerifyInstruction1=Um e-mail com instru\u00e7\u00f5es para verificar o seu endere\u00e7o de e-mail foi enviado para voc\u00ea.
-emailVerifyInstruction2=Voc\u00ea n\u00e3o recebeu um c\u00f3digo de verifica\u00e7\u00e3o em seu e-mail?
+emailVerifyInstruction1=Um e-mail com instru\u00E7\u00F5es para verificar o seu endere\u00E7o de e-mail foi enviado para voc\u00EA.
+emailVerifyInstruction2=Voc\u00EA n\u00E3o recebeu um c\u00F3digo de verifica\u00E7\u00E3o em seu e-mail?
emailVerifyInstruction3=para reenviar o e-mail.
backToLogin=« Voltar
-emailInstruction=Digite seu nome de usu\u00e1rio ou endere\u00e7o de email e n\u00f3s lhe enviaremos instru\u00e7\u00f5es sobre como criar uma nova senha.
+emailInstruction=Digite seu nome de usu\u00E1rio ou endere\u00E7o de email e n\u00F3s lhe enviaremos instru\u00E7\u00F5es sobre como criar uma nova senha.
-invalidUserMessage=Nome de usu\u00e1rio ou senha inv\u00e1lida.
-invalidEmailMessage=E-mail inv\u00e1lido.
+invalidUserMessage=Nome de usu\u00E1rio ou senha inv\u00E1lida.
+invalidEmailMessage=E-mail inv\u00E1lido.
accountDisabledMessage=Conta desativada, contate o administrador.
-accountTemporarilyDisabledMessage=Conta temporariamente indispon\u00edvel, contate o administrador ou tente novamente mais tarde.
-expiredCodeMessage=Tempo de login expirado. Por favor, fa\u00e7a login novamente.
+accountTemporarilyDisabledMessage=Conta temporariamente indispon\u00EDvel, contate o administrador ou tente novamente mais tarde.
+expiredCodeMessage=Tempo de login expirado. Por favor, fa\u00E7a login novamente.
missingFirstNameMessage=Por favor, informe o primeiro nome.
missingLastNameMessage=Por favor, informe o sobrenome.
missingEmailMessage=Por favor, informe o email.
-missingUsernameMessage=Por favor, informe o nome de usu\u00e1rio.
+missingUsernameMessage=Por favor, informe o nome de usu\u00E1rio.
missingPasswordMessage=Por favor, informe a senha.
-missingTotpMessage=Por favor, informe o c\u00f3digo autenticador.
-notMatchPasswordMessage=As senhas n\u00e3o coincidem.
+missingTotpMessage=Por favor, informe o c\u00F3digo autenticador.
+notMatchPasswordMessage=As senhas n\u00E3o coincidem.
-invalidPasswordExistingMessage=Senha atual inv\u00e1lida.
-invalidPasswordConfirmMessage=Senha de confirma\u00e7\u00e3o n\u00e3o coincide.
-invalidTotpMessage=C\u00f3digo autenticador inv\u00e1lido.
+invalidPasswordExistingMessage=Senha atual inv\u00E1lida.
+invalidPasswordConfirmMessage=Senha de confirma\u00E7\u00E3o n\u00E3o coincide.
+invalidTotpMessage=C\u00F3digo autenticador inv\u00E1lido.
-usernameExistsMessage=Nome de usu\u00e1rio j\u00e1 existe.
-emailExistsMessage=E-mail j\u00e1 existe.
+usernameExistsMessage=Nome de usu\u00E1rio j\u00E1 existe.
+emailExistsMessage=E-mail j\u00E1 existe.
-federatedIdentityEmailExistsMessage=J\u00e1 existe usu\u00e1rio com este e-mail. Por favor acesse sua conta de gest\u00e3o para vincular a conta.
-federatedIdentityUsernameExistsMessage=J\u00e1 existe usu\u00e1rio com este nome de usu\u00e1rio. Por favor acessar sua conta de gest\u00e3o para vincular a conta.
+federatedIdentityEmailExistsMessage=J\u00E1 existe usu\u00E1rio com este e-mail. Por favor acesse sua conta de gest\u00E3o para vincular a conta.
+federatedIdentityUsernameExistsMessage=J\u00E1 existe usu\u00E1rio com este nome de usu\u00E1rio. Por favor acessar sua conta de gest\u00E3o para vincular a conta.
-configureTotpMessage=Voc\u00ea precisa configurar seu celular com o autenticador Mobile para ativar sua conta.
-updateProfileMessage=Voc\u00ea precisa atualizar o seu perfil de usu\u00e1rio para ativar sua conta.
-updatePasswordMessage=Voc\u00ea precisa mudar sua senha para ativar sua conta.
-verifyEmailMessage=Voc\u00ea precisa verificar o seu endere\u00e7o de e-mail para ativar sua conta.
+configureTotpMessage=Voc\u00EA precisa configurar seu celular com o autenticador Mobile para ativar sua conta.
+updateProfileMessage=Voc\u00EA precisa atualizar o seu perfil de usu\u00E1rio para ativar sua conta.
+updatePasswordMessage=Voc\u00EA precisa mudar sua senha para ativar sua conta.
+verifyEmailMessage=Voc\u00EA precisa verificar o seu endere\u00E7o de e-mail para ativar sua conta.
-emailSentMessage=Voc\u00ea dever\u00e1 receber um e-mail em breve com mais instru\u00e7\u00f5es.
+emailSentMessage=Voc\u00EA dever\u00E1 receber um e-mail em breve com mais instru\u00E7\u00F5es.
emailSendErrorMessage=Falha ao enviar e-mail, por favor, tente novamente mais tarde
accountUpdatedMessage=Sua conta foi atualizada
@@ -94,52 +94,52 @@ accountPasswordUpdatedMessage=Sua senha foi atualizada
noAccessMessage=Sem acesso
-invalidPasswordMinLengthMessage=Senha inv\u00e1lida: comprimento m\u00ednimo {0}
-invalidPasswordMinDigitsMessage=Senha inv\u00e1lida: deve conter pelo menos {0} d\u00edgitos num\u00e9ricos
-invalidPasswordMinLowerCaseCharsMessage=Senha inv\u00e1lida: deve conter pelo menos {0} caracteres min\u00fasculos
-invalidPasswordMinUpperCaseCharsMessage=Senha inv\u00e1lida: deve conter pelo menos {0} caracteres mai\u00fasculos
-invalidPasswordMinSpecialCharsMessage=Senha inv\u00e1lida: deve conter pelo menos {0} caracteres especiais
-invalidPasswordNotUsernameMessage=Senha inv\u00e1lida: n\u00e3o deve ser igual ao nome de usu\u00e1rio
+invalidPasswordMinLengthMessage=Senha inv\u00E1lida: comprimento m\u00EDnimo {0}
+invalidPasswordMinDigitsMessage=Senha inv\u00E1lida: deve conter pelo menos {0} d\u00EDgitos num\u00E9ricos
+invalidPasswordMinLowerCaseCharsMessage=Senha inv\u00E1lida: deve conter pelo menos {0} caracteres min\u00FAsculos
+invalidPasswordMinUpperCaseCharsMessage=Senha inv\u00E1lida: deve conter pelo menos {0} caracteres mai\u00FAsculos
+invalidPasswordMinSpecialCharsMessage=Senha inv\u00E1lida: deve conter pelo menos {0} caracteres especiais
+invalidPasswordNotUsernameMessage=Senha inv\u00E1lida: n\u00E3o deve ser igual ao nome de usu\u00E1rio
failedToProcessResponseMessage=Falha ao processar a resposta
httpsRequiredMessage=HTTPS requerido
realmNotEnabledMessage=Realm desativado
-invalidRequestMessage=Pedido inv\u00e1lido
+invalidRequestMessage=Pedido inv\u00E1lido
unknownLoginRequesterMessage=Solicitante de login desconhecido
loginRequesterNotEnabledMessage=Solicitante de login desativado
-bearerOnlyMessage=Aplica\u00e7\u00f5es somente ao portador n\u00e3o tem permiss\u00e3o para iniciar o login pelo navegador
-directGrantsOnlyMessage=Clientes de concess\u00e3o direta n\u00e3o tem permiss\u00e3o para iniciar o login pelo navegador
-invalidRedirectUriMessage=URI de redirecionamento inv\u00e1lido
-unsupportedNameIdFormatMessage=NameIDFormat n\u00e3o suportado
-invlidRequesterMessage=Solicitante inv\u00e1lido
-registrationNotAllowedMessage=Registro n\u00e3o permitido.
-
-permissionNotApprovedMessage=Permiss\u00e3o n\u00e3o aprovada.
-noRelayStateInResponseMessage=Sem estado de retransmiss\u00e3o na resposta do provedor de identidade [{0}].
-identityProviderAlreadyLinkedMessage=A identidade retornado pelo provedor de identidade [{0}] j\u00e1 est\u00e1 vinculado a outro usu\u00e1rio.
-insufficientPermissionMessage=Permiss\u00f5es insuficientes para vincular identidades.
-couldNotProceedWithAuthenticationRequestMessage=N\u00e3o foi poss\u00edvel proceder \u00e0 solicita\u00e7\u00e3o de autentica\u00e7\u00e3o para provedor de identidade.
-couldNotObtainTokenMessage=N\u00e3o foi poss\u00edvel obter token do provedor de identidade [{0}].
+bearerOnlyMessage=Aplica\u00E7\u00F5es somente ao portador n\u00E3o tem permiss\u00E3o para iniciar o login pelo navegador
+directGrantsOnlyMessage=Clientes de concess\u00E3o direta n\u00E3o tem permiss\u00E3o para iniciar o login pelo navegador
+invalidRedirectUriMessage=URI de redirecionamento inv\u00E1lido
+unsupportedNameIdFormatMessage=NameIDFormat n\u00E3o suportado
+invlidRequesterMessage=Solicitante inv\u00E1lido
+registrationNotAllowedMessage=Registro n\u00E3o permitido.
+
+permissionNotApprovedMessage=Permiss\u00E3o n\u00E3o aprovada.
+noRelayStateInResponseMessage=Sem estado de retransmiss\u00E3o na resposta do provedor de identidade [{0}].
+identityProviderAlreadyLinkedMessage=A identidade retornado pelo provedor de identidade [{0}] j\u00E1 est\u00E1 vinculado a outro usu\u00E1rio.
+insufficientPermissionMessage=Permiss\u00F5es insuficientes para vincular identidades.
+couldNotProceedWithAuthenticationRequestMessage=N\u00E3o foi poss\u00EDvel proceder \u00E0 solicita\u00E7\u00E3o de autentica\u00E7\u00E3o para provedor de identidade.
+couldNotObtainTokenMessage=N\u00E3o foi poss\u00EDvel obter token do provedor de identidade [{0}].
unexpectedErrorRetrievingTokenMessage=Erro inesperado ao recuperar token do provedor de identidade [{0}].
unexpectedErrorHandlingResponseMessage=Erro inesperado ao manusear resposta do provedor de identidade [{0}].
-identityProviderAuthenticationFailedMessage=Falha na autentica\u00e7\u00e3o. N\u00e3o foi poss\u00edvel autenticar com o provedor de identidade [{0}].
-couldNotSendAuthenticationRequestMessage=N\u00e3o foi poss\u00edvel enviar solicita\u00e7\u00e3o de autentica\u00e7\u00e3o para o provedor de identidade [{0}].
-unexpectedErrorHandlingRequestMessage=Erro inesperado ao manusear pedido de autentica\u00e7\u00e3o para provedor de identidade [{0}].
-invalidAccessCodeMessage=C\u00f3digo de acesso inv\u00e1lido.
-sessionNotActiveMessage=Sess\u00e3o inativa.
-unknownCodeMessage=C\u00f3digo desconhecido, fa\u00e7a o login novamente atrav\u00e9s de sua aplica\u00e7\u00e3o.
-invalidCodeMessage=C\u00f3digo inv\u00e1lido, por favor fa\u00e7a login novamente atrav\u00e9s de sua aplica\u00e7\u00e3o.
-identityProviderUnexpectedErrorMessage=Erro inesperado durante a autentica\u00e7\u00e3o com o provedor de identidade
-identityProviderNotFoundMessage=N\u00e3o foi poss\u00edvel encontrar um provedor de identidade com o identificador [{0}].
-realmSupportsNoCredentialsMessage=O realm [{0}] n\u00e3o suporta qualquer tipo de credencial.
-identityProviderNotUniqueMessage=O realm [{0}] suporta m\u00faltiplos provedores de identidade. N\u00e3o foi poss\u00edvel determinar qual o provedor de identidade deve ser usado para se autenticar.
-emailVerifiedMessage=O seu endere\u00e7o de e-mail foi confirmado.
+identityProviderAuthenticationFailedMessage=Falha na autentica\u00E7\u00E3o. N\u00E3o foi poss\u00EDvel autenticar com o provedor de identidade [{0}].
+couldNotSendAuthenticationRequestMessage=N\u00E3o foi poss\u00EDvel enviar solicita\u00E7\u00E3o de autentica\u00E7\u00E3o para o provedor de identidade [{0}].
+unexpectedErrorHandlingRequestMessage=Erro inesperado ao manusear pedido de autentica\u00E7\u00E3o para provedor de identidade [{0}].
+invalidAccessCodeMessage=C\u00F3digo de acesso inv\u00E1lido.
+sessionNotActiveMessage=Sess\u00E3o inativa.
+unknownCodeMessage=C\u00F3digo desconhecido, fa\u00E7a o login novamente atrav\u00E9s de sua aplica\u00E7\u00E3o.
+invalidCodeMessage=C\u00F3digo inv\u00E1lido, por favor fa\u00E7a login novamente atrav\u00E9s de sua aplica\u00E7\u00E3o.
+identityProviderUnexpectedErrorMessage=Erro inesperado durante a autentica\u00E7\u00E3o com o provedor de identidade
+identityProviderNotFoundMessage=N\u00E3o foi poss\u00EDvel encontrar um provedor de identidade com o identificador [{0}].
+realmSupportsNoCredentialsMessage=O realm [{0}] n\u00E3o suporta qualquer tipo de credencial.
+identityProviderNotUniqueMessage=O realm [{0}] suporta m\u00FAltiplos provedores de identidade. N\u00E3o foi poss\u00EDvel determinar qual o provedor de identidade deve ser usado para se autenticar.
+emailVerifiedMessage=O seu endere\u00E7o de e-mail foi confirmado.
locale_de=Deutsch
locale_en=English
-locale_pt-BR=Portugu\u00eas (BR)
+locale_pt-BR=Portugu\u00EAs (BR)
-backToApplication=« Voltar para a aplica\u00e7\u00e3o
-missingParameterMessage=Par\u00e2metros que faltam\: {0}
-clientNotFoundMessage=Cliente n\u00e3o encontrado.
-invalidParameterMessage=Par\u00e2mentro inv\u00e1lido\: {0}
\ No newline at end of file
+backToApplication=« Voltar para a aplica\u00E7\u00E3o
+missingParameterMessage=Par\u00E2metros que faltam\: {0}
+clientNotFoundMessage=Cliente n\u00E3o encontrado.
+invalidParameterMessage=Par\u00E2mentro inv\u00E1lido\: {0}
\ No newline at end of file
diff --git a/forms/common-themes/src/main/resources/theme/keycloak/email/email-verification.ftl b/forms/common-themes/src/main/resources/theme/keycloak/email/email-verification.ftl
index 5f2490b..0ae601f 100644
--- a/forms/common-themes/src/main/resources/theme/keycloak/email/email-verification.ftl
+++ b/forms/common-themes/src/main/resources/theme/keycloak/email/email-verification.ftl
@@ -1 +1 @@
-${msg("emailVerificationBody",link, linkExpiration)}
\ No newline at end of file
+${msg("emailVerificationBody",link, linkExpiration, realmName)}
\ No newline at end of file
diff --git a/forms/common-themes/src/main/resources/theme/keycloak/email/messages/messages_de.properties b/forms/common-themes/src/main/resources/theme/keycloak/email/messages/messages_de.properties
index 60228c3..0256640 100644
--- a/forms/common-themes/src/main/resources/theme/keycloak/email/messages/messages_de.properties
+++ b/forms/common-themes/src/main/resources/theme/keycloak/email/messages/messages_de.properties
@@ -1,12 +1,12 @@
emailVerificationSubject=E-Mail verifizieren
-passwordResetSubject=Passwort zur�ckzusetzen
-passwordResetBody=Jemand hat angefordert Ihr Keycloak Passwort zur�ckzusetzen. Falls das Sie waren, dann klicken Sie auf den folgenden Link um das Passwort zur�ckzusetzen.\n\n{0}\n\nDieser Link wird in {1} Minuten ablaufen.\n\nFalls Sie das Passwort nicht zur�cksetzen m�chten, dann k�nnen Sie diese E-Mail ignorieren.
-emailVerificationBody=Jemand hat ein Keycloak Konto mit dieser E-Mail Adresse erstellt. Fall das Sie waren, dann klicken Sie auf den Link um die E-Mail Adresse zu verifizieren.\n\n{0}\n\nDieser Link wird in {1} Minuten ablaufen.\n\nFalls Sie dieses Konto nicht erstellt haben, dann k�nnen sie diese Nachricht ignorieren.
+passwordResetSubject=Passwort zur\u00FCckzusetzen
+passwordResetBody=Jemand hat angefordert Ihr {2} Passwort zur\u00FCckzusetzen. Falls das Sie waren, dann klicken Sie auf den folgenden Link um das Passwort zur\u00FCckzusetzen.\n\n{0}\n\nDieser Link wird in {1} Minuten ablaufen.\n\nFalls Sie das Passwort nicht zur\u00FCcksetzen m\u00F6chten, dann k\u00F6nnen Sie diese E-Mail ignorieren.
+emailVerificationBody=Jemand hat ein {2} Konto mit dieser E-Mail Adresse erstellt. Fall das Sie waren, dann klicken Sie auf den Link um die E-Mail Adresse zu verifizieren.\n\n{0}\n\nDieser Link wird in {1} Minuten ablaufen.\n\nFalls Sie dieses Konto nicht erstellt haben, dann k\u00F6nnen sie diese Nachricht ignorieren.
eventLoginErrorSubject=Fehlgeschlagene Anmeldung
eventLoginErrorBody=Jemand hat um {0} von {1} versucht sich mit ihrem Konto anzumelden. Falls das nicht Sie waren, dann kontaktieren Sie bitte Ihren Admin.
eventRemoveTotpSubject=TOTP Entfernt
eventRemoveTotpBody=TOTP wurde von ihrem Konto am {0} von {1} entfernt. Falls das nicht Sie waren, dann kontaktieren Sie bitte Ihren Admin.
eventUpdatePasswordSubject=Passwort Aktualisiert
-eventUpdatePasswordBody=Ihr Passwort wurde am {0} von {1} ge�ndert. Falls das nicht Sie waren, dann kontaktieren Sie bitte Ihren Admin.
+eventUpdatePasswordBody=Ihr Passwort wurde am {0} von {1} ge\u00E4ndert. Falls das nicht Sie waren, dann kontaktieren Sie bitte Ihren Admin.
eventUpdateTotpSubject=TOTP Aktualisiert
-eventUpdateTotpBody=TOTP wurde am {0} von {1} ge�ndert. Falls das nicht Sie waren, dann kontaktieren Sie bitte Ihren Admin.
+eventUpdateTotpBody=TOTP wurde am {0} von {1} ge\u00E4ndert. Falls das nicht Sie waren, dann kontaktieren Sie bitte Ihren Admin.
diff --git a/forms/common-themes/src/main/resources/theme/keycloak/email/messages/messages_en.properties b/forms/common-themes/src/main/resources/theme/keycloak/email/messages/messages_en.properties
index c23daf6..c0afc9c 100755
--- a/forms/common-themes/src/main/resources/theme/keycloak/email/messages/messages_en.properties
+++ b/forms/common-themes/src/main/resources/theme/keycloak/email/messages/messages_en.properties
@@ -1,7 +1,7 @@
emailVerificationSubject=Verify email
-emailVerificationBody=Someone has created a Keycloak account with this email address. If this was you, click the link below to verify your email address\n\n{0}\n\nThis link will expire within {1} minutes.\n\nIf you didn''t create this account, just ignore this message.
+emailVerificationBody=Someone has created a {2} account with this email address. If this was you, click the link below to verify your email address\n\n{0}\n\nThis link will expire within {1} minutes.\n\nIf you didn''t create this account, just ignore this message.
passwordResetSubject=Reset password
-passwordResetBody=Someone just requested to change your Keycloak account''s password. If this was you, click on the link below to set a new password\n\n{0}\n\nThis link will expire within {1} minutes.\n\nIf you don''t want to reset your password, just ignore this message and nothing will be changed.
+passwordResetBody=Someone just requested to change your {2} account''s password. If this was you, click on the link below to set a new password\n\n{0}\n\nThis link will expire within {1} minutes.\n\nIf you don''t want to reset your password, just ignore this message and nothing will be changed.
eventLoginErrorSubject=Login error
eventLoginErrorBody=A failed login attempt was dettected to your account on {0} from {1}. If this was not you, please contact an admin.
eventRemoveTotpSubject=Remove TOTP
@@ -9,4 +9,4 @@ eventRemoveTotpBody=TOTP was removed from your account on {0} from {1}. If this
eventUpdatePasswordSubject=Update password
eventUpdatePasswordBody=Your password was changed on {0} from {1}. If this was not you, please contact an admin.
eventUpdateTotpSubject=Update TOTP
-eventUpdateTotpBody=TOTP was updated for your account on {0} from {1}. If this was not you, please contact an admin.
+eventUpdateTotpBody=TOTP was updated for your account on {0} from {1}. If this was not you, please contact an admin.
\ No newline at end of file
diff --git a/forms/common-themes/src/main/resources/theme/keycloak/email/messages/messages_pt_BR.properties b/forms/common-themes/src/main/resources/theme/keycloak/email/messages/messages_pt_BR.properties
index 57a20f1..0316e19 100644
--- a/forms/common-themes/src/main/resources/theme/keycloak/email/messages/messages_pt_BR.properties
+++ b/forms/common-themes/src/main/resources/theme/keycloak/email/messages/messages_pt_BR.properties
@@ -1,12 +1,12 @@
-emailVerificationSubject=Verifica\u00e7\u00e3o de e-mail
-emailVerificationBody=Algu\u00e9m criou uma conta Keycloak com este endere\u00e7o de e-mail. Se foi voc\u00ea, clique no link abaixo para verificar o seu endere\u00e7o de email\n\n{0}\n\nEste link ir\u00e1 expirar dentro de {1} minutos.\n\nSe n\u00e3o foi voc\u00ea que criou esta conta, basta ignorar esta mensagem.
-passwordResetSubject=Redefini\u00e7\u00e3o de senha
-passwordResetBody=Algu\u00e9m pediu para mudar a senha de sua conta Keycloak. Se foi voc\u00ea, clique no link abaixo para definir uma nova senha\n\n{0}\n\nEste link ir\u00e1 expirar dentro de {1} minutos.\n\nSe voc\u00ea n\u00e3o deseja redefinir sua senha, basta ignorar esta mensagem e nada ser\u00e1 mudado.
+emailVerificationSubject=Verifica\u00E7\u00E3o de e-mail
+emailVerificationBody=Algu\u00E9m criou uma conta {2} com este endere\u00E7o de e-mail. Se foi voc\u00EA, clique no link abaixo para verificar o seu endere\u00E7o de email\n\n{0}\n\nEste link ir\u00E1 expirar dentro de {1} minutos.\n\nSe n\u00E3o foi voc\u00EA que criou esta conta, basta ignorar esta mensagem.
+passwordResetSubject=Redefini\u00E7\u00E3o de senha
+passwordResetBody=Algu\u00E9m pediu para mudar a senha de sua conta {2}. Se foi voc\u00EA, clique no link abaixo para definir uma nova senha\n\n{0}\n\nEste link ir\u00E1 expirar dentro de {1} minutos.\n\nSe voc\u00EA n\u00E3o deseja redefinir sua senha, basta ignorar esta mensagem e nada ser\u00E1 mudado.
eventLoginErrorSubject=Erro de login
-eventLoginErrorBody=Uma tentativa de login mal sucedida para a sua conta foi detectada em {0} de {1}. Se n\u00e3o foi voc\u00ea, por favor, entre em contato com um administrador.
+eventLoginErrorBody=Uma tentativa de login mal sucedida para a sua conta foi detectada em {0} de {1}. Se n\u00E3o foi voc\u00EA, por favor, entre em contato com um administrador.
eventRemoveTotpSubject=Remover TOTP
-eventRemoveTotpBody=TOTP foi removido da sua conta em {0} de {1}. Se n\u00e3o foi voc\u00ea, por favor, entre em contato com um administrador.
-eventUpdatePasswordSubject=Atualiza\u00e7\u00e3o de senha
-eventUpdatePasswordBody=Sua senha foi alterada em {0} de {1}. Se n\u00e3o foi voc\u00ea, por favor, entre em contato com um administrador.
-eventUpdateTotpSubject=Atualiza\u00e7\u00e3o TOTP
-eventUpdateTotpBody=TOTP foi atualizado para a sua conta em {0} de {1}. Se n\u00e3o foi voc\u00ea, por favor, entre em contato com um administrador.
+eventRemoveTotpBody=TOTP foi removido da sua conta em {0} de {1}. Se n\u00E3o foi voc\u00EA, por favor, entre em contato com um administrador.
+eventUpdatePasswordSubject=Atualiza\u00E7\u00E3o de senha
+eventUpdatePasswordBody=Sua senha foi alterada em {0} de {1}. Se n\u00E3o foi voc\u00EA, por favor, entre em contato com um administrador.
+eventUpdateTotpSubject=Atualiza\u00E7\u00E3o TOTP
+eventUpdateTotpBody=TOTP foi atualizado para a sua conta em {0} de {1}. Se n\u00E3o foi voc\u00EA, por favor, entre em contato com um administrador.
diff --git a/forms/common-themes/src/main/resources/theme/keycloak/email/password-reset.ftl b/forms/common-themes/src/main/resources/theme/keycloak/email/password-reset.ftl
index d7150d6..aba4fd1 100644
--- a/forms/common-themes/src/main/resources/theme/keycloak/email/password-reset.ftl
+++ b/forms/common-themes/src/main/resources/theme/keycloak/email/password-reset.ftl
@@ -1 +1 @@
-${msg("passwordResetBody",link, linkExpiration)}
\ No newline at end of file
+${msg("passwordResetBody",link, linkExpiration, realmName)}
\ No newline at end of file
diff --git a/forms/email-freemarker/src/main/java/org/keycloak/email/freemarker/FreeMarkerEmailProvider.java b/forms/email-freemarker/src/main/java/org/keycloak/email/freemarker/FreeMarkerEmailProvider.java
index 505a416..95f55f3 100755
--- a/forms/email-freemarker/src/main/java/org/keycloak/email/freemarker/FreeMarkerEmailProvider.java
+++ b/forms/email-freemarker/src/main/java/org/keycloak/email/freemarker/FreeMarkerEmailProvider.java
@@ -66,6 +66,9 @@ public class FreeMarkerEmailProvider implements EmailProvider {
attributes.put("link", link);
attributes.put("linkExpiration", expirationInMinutes);
+ String realmName = realm.getName().substring(0, 1).toUpperCase() + realm.getName().substring(1);
+ attributes.put("realmName", realmName);
+
send("passwordResetSubject", "password-reset.ftl", attributes);
}
@@ -75,6 +78,9 @@ public class FreeMarkerEmailProvider implements EmailProvider {
attributes.put("link", link);
attributes.put("linkExpiration", expirationInMinutes);
+ String realmName = realm.getName().substring(0, 1).toUpperCase() + realm.getName().substring(1);
+ attributes.put("realmName", realmName);
+
send("emailVerificationSubject", "email-verification.ftl", attributes);
}
diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/BearerTokenRequestAuthenticator.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/BearerTokenRequestAuthenticator.java
index 81b1d42..a1a68df 100755
--- a/integration/adapter-core/src/main/java/org/keycloak/adapters/BearerTokenRequestAuthenticator.java
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/BearerTokenRequestAuthenticator.java
@@ -64,7 +64,7 @@ public class BearerTokenRequestAuthenticator {
protected AuthOutcome authenticateToken(HttpFacade exchange, String tokenString) {
try {
- token = RSATokenVerifier.verifyToken(tokenString, deployment.getRealmKey(), deployment.getRealm());
+ token = RSATokenVerifier.verifyToken(tokenString, deployment.getRealmKey(), deployment.getRealmInfoUrl());
} catch (VerificationException e) {
log.error("Failed to verify token", e);
challenge = challengeResponse(exchange, "invalid_token", e.getMessage());
diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/CookieTokenStore.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/CookieTokenStore.java
index 31bbe0a..526756d 100755
--- a/integration/adapter-core/src/main/java/org/keycloak/adapters/CookieTokenStore.java
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/CookieTokenStore.java
@@ -54,7 +54,7 @@ public class CookieTokenStore {
try {
// Skip check if token is active now. It's supposed to be done later by the caller
- AccessToken accessToken = RSATokenVerifier.verifyToken(accessTokenString, deployment.getRealmKey(), deployment.getRealm(), false);
+ AccessToken accessToken = RSATokenVerifier.verifyToken(accessTokenString, deployment.getRealmKey(), deployment.getRealmInfoUrl(), false);
IDToken idToken;
if (idTokenString != null && idTokenString.length() > 0) {
JWSInput input = new JWSInput(idTokenString);
diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/jaas/AbstractKeycloakLoginModule.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/jaas/AbstractKeycloakLoginModule.java
index a5b56fe..5b6c55d 100644
--- a/integration/adapter-core/src/main/java/org/keycloak/adapters/jaas/AbstractKeycloakLoginModule.java
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/jaas/AbstractKeycloakLoginModule.java
@@ -173,7 +173,7 @@ public abstract class AbstractKeycloakLoginModule implements LoginModule {
protected Auth bearerAuth(String tokenString) throws VerificationException {
- AccessToken token = RSATokenVerifier.verifyToken(tokenString, deployment.getRealmKey(), deployment.getRealm());
+ AccessToken token = RSATokenVerifier.verifyToken(tokenString, deployment.getRealmKey(), deployment.getRealmInfoUrl());
boolean verifyCaller;
if (deployment.isUseResourceRoleMappings()) {
diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java
index bd2012f..68688e6 100755
--- a/integration/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java
@@ -311,7 +311,7 @@ public class OAuthRequestAuthenticator {
refreshToken = tokenResponse.getRefreshToken();
idTokenString = tokenResponse.getIdToken();
try {
- token = RSATokenVerifier.verifyToken(tokenString, deployment.getRealmKey(), deployment.getRealm());
+ token = RSATokenVerifier.verifyToken(tokenString, deployment.getRealmKey(), deployment.getRealmInfoUrl());
if (idTokenString != null) {
JWSInput input = new JWSInput(idTokenString);
try {
diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/RefreshableKeycloakSecurityContext.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/RefreshableKeycloakSecurityContext.java
index 8c0dc91..342ee35 100755
--- a/integration/adapter-core/src/main/java/org/keycloak/adapters/RefreshableKeycloakSecurityContext.java
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/RefreshableKeycloakSecurityContext.java
@@ -107,7 +107,7 @@ public class RefreshableKeycloakSecurityContext extends KeycloakSecurityContext
String tokenString = response.getToken();
AccessToken token = null;
try {
- token = RSATokenVerifier.verifyToken(tokenString, deployment.getRealmKey(), deployment.getRealm());
+ token = RSATokenVerifier.verifyToken(tokenString, deployment.getRealmKey(), deployment.getRealmInfoUrl());
log.debug("Token Verification succeeded!");
} catch (VerificationException e) {
log.error("failed verification of token");
diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ApplicationResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ApplicationResource.java
index 458135c..2601d53 100755
--- a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ApplicationResource.java
+++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ApplicationResource.java
@@ -1,8 +1,6 @@
package org.keycloak.admin.client.resource;
-import org.jboss.resteasy.annotations.cache.NoCache;
import org.keycloak.representations.idm.ApplicationRepresentation;
-import org.keycloak.representations.idm.ClaimRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.UserSessionRepresentation;
@@ -25,6 +23,9 @@ import java.util.Set;
*/
public interface ApplicationResource {
+ @Path("protocol-mappers")
+ public ProtocolMappersResource getProtocolMappers();
+
@GET
@Produces(MediaType.APPLICATION_JSON)
public ApplicationRepresentation toRepresentation();
@@ -51,16 +52,6 @@ public interface ApplicationResource {
@Consumes(MediaType.APPLICATION_JSON)
public void removeAllowedOrigins(Set<String> originsToRemove);
- @GET
- @Path("claims")
- @Produces(MediaType.APPLICATION_JSON)
- public ClaimRepresentation getClaims();
-
- @PUT
- @Path("claims")
- @Consumes(MediaType.APPLICATION_JSON)
- public void updateClaims(ClaimRepresentation claimRepresentation);
-
@POST
@Path("client-secret")
@Produces(MediaType.APPLICATION_JSON)
diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/OAuthClientResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/OAuthClientResource.java
index 5d08748..a2effee 100755
--- a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/OAuthClientResource.java
+++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/OAuthClientResource.java
@@ -1,6 +1,5 @@
package org.keycloak.admin.client.resource;
-import org.keycloak.representations.idm.ClaimRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.OAuthClientRepresentation;
@@ -16,37 +15,40 @@ import javax.ws.rs.core.MediaType;
/**
* @author rodrigo.sasaki@icarros.com.br
*/
-@Consumes(MediaType.APPLICATION_JSON)
-@Produces(MediaType.APPLICATION_JSON)
public interface OAuthClientResource {
+ @Path("protocol-mappers")
+ public ProtocolMappersResource getProtocolMappers();
+
+ // TODO
+ // @Path("certificates/{attr}")
+ // public ClientAttributeCertificateResource getCertficateResource(@PathParam("attr") String attributePrefix);
+
@GET
+ @Produces(MediaType.APPLICATION_JSON)
public OAuthClientRepresentation toRepresentation();
@PUT
+ @Consumes(MediaType.APPLICATION_JSON)
public void update(OAuthClientRepresentation oAuthClientRepresentation);
@DELETE
public void remove();
- @GET
- @Path("claims")
- public ClaimRepresentation getClaims();
-
- @PUT
- @Path("claims")
- public ClaimRepresentation updateClaims(ClaimRepresentation claimRepresentation);
-
@POST
@Path("client-secret")
+ @Consumes("application/json")
+ @Produces(MediaType.APPLICATION_JSON)
public CredentialRepresentation generateNewSecret();
@GET
@Path("client-secret")
+ @Produces(MediaType.APPLICATION_JSON)
public CredentialRepresentation getSecret();
@GET
@Path("installation")
+ @Produces(MediaType.APPLICATION_JSON)
public String getInstallationJson();
@Path("/scope-mappings")
diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ProtocolMappersResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ProtocolMappersResource.java
new file mode 100644
index 0000000..40e505f
--- /dev/null
+++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ProtocolMappersResource.java
@@ -0,0 +1,55 @@
+package org.keycloak.admin.client.resource;
+
+import java.util.List;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Response;
+
+import org.keycloak.representations.idm.ProtocolMapperRepresentation;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public interface ProtocolMappersResource {
+
+ @GET
+ @Path("protocol/{protocol}")
+ @Produces("application/json")
+ public List<ProtocolMapperRepresentation> getMappersPerProtocol(@PathParam("protocol") String protocol);
+
+ @Path("models")
+ @POST
+ @Consumes("application/json")
+ public Response createMapper(ProtocolMapperRepresentation rep);
+
+ @Path("add-models")
+ @POST
+ @Consumes("application/json")
+ public void createMapper(List<ProtocolMapperRepresentation> reps);
+
+ @GET
+ @Path("models")
+ @Produces("application/json")
+ public List<ProtocolMapperRepresentation> getMappers();
+
+ @GET
+ @Path("models/{id}")
+ @Produces("application/json")
+ public ProtocolMapperRepresentation getMapperById(@PathParam("id") String id);
+
+ @PUT
+ @Path("models/{id}")
+ @Consumes("application/json")
+ public void update(@PathParam("id") String id, ProtocolMapperRepresentation rep);
+
+ @DELETE
+ @Path("models/{id}")
+ public void delete(@PathParam("id") String id);
+}
diff --git a/integration/installed/src/main/java/org/keycloak/adapters/installed/KeycloakInstalled.java b/integration/installed/src/main/java/org/keycloak/adapters/installed/KeycloakInstalled.java
index e69f6c8..cc2aeb1 100644
--- a/integration/installed/src/main/java/org/keycloak/adapters/installed/KeycloakInstalled.java
+++ b/integration/installed/src/main/java/org/keycloak/adapters/installed/KeycloakInstalled.java
@@ -193,7 +193,7 @@ public class KeycloakInstalled {
refreshToken = tokenResponse.getRefreshToken();
idTokenString = tokenResponse.getIdToken();
- token = RSATokenVerifier.verifyToken(tokenString, deployment.getRealmKey(), deployment.getRealm());
+ token = RSATokenVerifier.verifyToken(tokenString, deployment.getRealmKey(), deployment.getRealmInfoUrl());
if (idTokenString != null) {
JWSInput input = new JWSInput(idTokenString);
try {
diff --git a/model/api/src/main/java/org/keycloak/migration/MigrationProvider.java b/model/api/src/main/java/org/keycloak/migration/MigrationProvider.java
new file mode 100644
index 0000000..784ba8e
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/migration/MigrationProvider.java
@@ -0,0 +1,20 @@
+package org.keycloak.migration;
+
+import java.util.List;
+import org.keycloak.provider.Provider;
+import org.keycloak.representations.idm.ProtocolMapperRepresentation;
+
+/**
+ * Various common utils needed for migration from older version to newer
+ *
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public interface MigrationProvider extends Provider {
+
+ /**
+ * @param claimMask mask used on ClientModel in 1.1.0
+ * @return set of 1.2.0.Beta1 protocol mappers corresponding to given claimMask
+ */
+ List<ProtocolMapperRepresentation> getMappersForClaimMask(Long claimMask);
+
+}
diff --git a/model/api/src/main/java/org/keycloak/migration/MigrationProviderFactory.java b/model/api/src/main/java/org/keycloak/migration/MigrationProviderFactory.java
new file mode 100644
index 0000000..a147ef7
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/migration/MigrationProviderFactory.java
@@ -0,0 +1,9 @@
+package org.keycloak.migration;
+
+import org.keycloak.provider.ProviderFactory;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public interface MigrationProviderFactory extends ProviderFactory<MigrationProvider> {
+}
diff --git a/model/api/src/main/java/org/keycloak/migration/MigrationSpi.java b/model/api/src/main/java/org/keycloak/migration/MigrationSpi.java
new file mode 100644
index 0000000..f6b768c
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/migration/MigrationSpi.java
@@ -0,0 +1,26 @@
+package org.keycloak.migration;
+
+import org.keycloak.provider.Provider;
+import org.keycloak.provider.ProviderFactory;
+import org.keycloak.provider.Spi;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class MigrationSpi implements Spi {
+
+ @Override
+ public String getName() {
+ return "migration";
+ }
+
+ @Override
+ public Class<? extends Provider> getProviderClass() {
+ return MigrationProvider.class;
+ }
+
+ @Override
+ public Class<? extends ProviderFactory> getProviderFactoryClass() {
+ return MigrationProviderFactory.class;
+ }
+}
diff --git a/model/api/src/main/java/org/keycloak/models/ClientModel.java b/model/api/src/main/java/org/keycloak/models/ClientModel.java
index 39e4d17..e9de509 100755
--- a/model/api/src/main/java/org/keycloak/models/ClientModel.java
+++ b/model/api/src/main/java/org/keycloak/models/ClientModel.java
@@ -30,10 +30,6 @@ public interface ClientModel {
*/
String getClientId();
- long getAllowedClaimsMask();
-
- void setAllowedClaimsMask(long mask);
-
Set<String> getWebOrigins();
void setWebOrigins(Set<String> webOrigins);
diff --git a/model/api/src/main/java/org/keycloak/models/entities/ClientEntity.java b/model/api/src/main/java/org/keycloak/models/entities/ClientEntity.java
index 8ba2ef0..9c24072 100755
--- a/model/api/src/main/java/org/keycloak/models/entities/ClientEntity.java
+++ b/model/api/src/main/java/org/keycloak/models/entities/ClientEntity.java
@@ -56,14 +56,6 @@ public class ClientEntity extends AbstractIdentifiableEntity {
this.secret = secret;
}
- public long getAllowedClaimsMask() {
- return allowedClaimsMask;
- }
-
- public void setAllowedClaimsMask(long allowedClaimsMask) {
- this.allowedClaimsMask = allowedClaimsMask;
- }
-
public int getNotBefore() {
return notBefore;
}
diff --git a/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java b/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java
index 30157e0..af0b92d 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java
@@ -178,7 +178,6 @@ public final class KeycloakModelUtils {
ApplicationModel app = realm.addApplication(name);
generateSecret(app);
app.setFullScopeAllowed(true);
- app.setAllowedClaimsMask(ClaimMask.ALL);
return app;
}
diff --git a/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java b/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
index 7e88c9a..1ff0b01 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
@@ -192,21 +192,6 @@ public class ModelToRepresentation {
return rep;
}
- public static ClaimRepresentation toRepresentation(ClientModel model) {
- ClaimRepresentation rep = new ClaimRepresentation();
- rep.setAddress(ClaimMask.hasAddress(model.getAllowedClaimsMask()));
- rep.setEmail(ClaimMask.hasEmail(model.getAllowedClaimsMask()));
- rep.setGender(ClaimMask.hasGender(model.getAllowedClaimsMask()));
- rep.setLocale(ClaimMask.hasLocale(model.getAllowedClaimsMask()));
- rep.setName(ClaimMask.hasName(model.getAllowedClaimsMask()));
- rep.setPhone(ClaimMask.hasPhone(model.getAllowedClaimsMask()));
- rep.setPicture(ClaimMask.hasPicture(model.getAllowedClaimsMask()));
- rep.setProfile(ClaimMask.hasProfile(model.getAllowedClaimsMask()));
- rep.setWebsite(ClaimMask.hasWebsite(model.getAllowedClaimsMask()));
- rep.setUsername(ClaimMask.hasUsername(model.getAllowedClaimsMask()));
- return rep;
- }
-
public static FederatedIdentityRepresentation toRepresentation(FederatedIdentityModel socialLink) {
FederatedIdentityRepresentation rep = new FederatedIdentityRepresentation();
rep.setUserName(socialLink.getUserName());
diff --git a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
index b23a367..85e724c 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
@@ -3,6 +3,7 @@ package org.keycloak.models.utils;
import net.iharder.Base64;
import org.jboss.logging.Logger;
import org.keycloak.enums.SslRequired;
+import org.keycloak.migration.MigrationProvider;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.BrowserSecurityHeaders;
import org.keycloak.models.ClaimMask;
@@ -129,7 +130,7 @@ public class RepresentationToModel {
importIdentityProviders(rep, newRealm);
if (rep.getApplications() != null) {
- Map<String, ApplicationModel> appMap = createApplications(rep, newRealm);
+ Map<String, ApplicationModel> appMap = createApplications(session, rep, newRealm);
}
if (rep.getRoles() != null) {
@@ -189,7 +190,7 @@ public class RepresentationToModel {
}
if (rep.getOauthClients() != null) {
- createOAuthClients(rep, newRealm);
+ createOAuthClients(session, rep, newRealm);
}
@@ -302,6 +303,7 @@ public class RepresentationToModel {
federatedIdentity.setIdentityProvider(social.getSocialProvider());
federatedIdentity.setUserId(social.getSocialUserId());
federatedIdentity.setUserName(social.getSocialUsername());
+ federatedIdentities.add(federatedIdentity);
}
user.setFederatedIdentities(federatedIdentities);
}
@@ -309,6 +311,16 @@ public class RepresentationToModel {
user.setSocialLinks(null);
}
+ private static List<ProtocolMapperRepresentation> convertDeprecatedClaimsMask(KeycloakSession session, ClaimRepresentation claimRep) {
+ if (claimRep == null) {
+ return null;
+ }
+
+ long mask = getClaimsMask(claimRep);
+ MigrationProvider migrationProvider = session.getProvider(MigrationProvider.class);
+ return migrationProvider.getMappersForClaimMask(mask);
+ }
+
public static void updateRealm(RealmRepresentation rep, RealmModel realm) {
if (rep.getRealm() != null) {
realm.setName(rep.getRealm());
@@ -435,10 +447,10 @@ public class RepresentationToModel {
// APPLICATIONS
- private static Map<String, ApplicationModel> createApplications(RealmRepresentation rep, RealmModel realm) {
+ private static Map<String, ApplicationModel> createApplications(KeycloakSession session, RealmRepresentation rep, RealmModel realm) {
Map<String, ApplicationModel> appMap = new HashMap<String, ApplicationModel>();
for (ApplicationRepresentation resourceRep : rep.getApplications()) {
- ApplicationModel app = createApplication(realm, resourceRep, false);
+ ApplicationModel app = createApplication(session, realm, resourceRep, false);
appMap.put(app.getName(), app);
}
return appMap;
@@ -451,8 +463,16 @@ public class RepresentationToModel {
* @param resourceRep
* @return
*/
- public static ApplicationModel createApplication(RealmModel realm, ApplicationRepresentation resourceRep, boolean addDefaultRoles) {
+ public static ApplicationModel createApplication(KeycloakSession session, RealmModel realm, ApplicationRepresentation resourceRep, boolean addDefaultRoles) {
logger.debug("************ CREATE APPLICATION: {0}" + resourceRep.getName());
+
+ if (resourceRep.getProtocolMappers() == null) {
+ List<ProtocolMapperRepresentation> convertedProtocolMappers = convertDeprecatedClaimsMask(session, resourceRep.getClaims());
+ if (convertedProtocolMappers != null) {
+ resourceRep.setProtocolMappers(convertedProtocolMappers);
+ }
+ }
+
ApplicationModel applicationModel = resourceRep.getId()!=null ? realm.addApplication(resourceRep.getId(), resourceRep.getName()) : realm.addApplication(resourceRep.getName());
if (resourceRep.isEnabled() != null) applicationModel.setEnabled(resourceRep.isEnabled());
applicationModel.setManagementUrl(resourceRep.getAdminUrl());
@@ -595,8 +615,9 @@ public class RepresentationToModel {
updateClientIdentityProviders(rep.getIdentityProviders(), resource);
}
- public static void setClaims(ClientModel model, ClaimRepresentation rep) {
- long mask = model.getAllowedClaimsMask();
+ public static long getClaimsMask(ClaimRepresentation rep) {
+ long mask = ClaimMask.ALL;
+
if (rep.getAddress()) {
mask |= ClaimMask.ADDRESS;
} else {
@@ -647,14 +668,14 @@ public class RepresentationToModel {
} else {
mask &= ~ClaimMask.WEBSITE;
}
- model.setAllowedClaimsMask(mask);
+ return mask;
}
// OAuth clients
- private static void createOAuthClients(RealmRepresentation realmRep, RealmModel realm) {
+ private static void createOAuthClients(KeycloakSession session, RealmRepresentation realmRep, RealmModel realm) {
for (OAuthClientRepresentation rep : realmRep.getOauthClients()) {
- createOAuthClient(rep, realm);
+ createOAuthClient(session, rep, realm);
}
}
@@ -664,25 +685,29 @@ public class RepresentationToModel {
return model;
}
- public static OAuthClientModel createOAuthClient(OAuthClientRepresentation rep, RealmModel realm) {
+ public static OAuthClientModel createOAuthClient(KeycloakSession session, OAuthClientRepresentation rep, RealmModel realm) {
OAuthClientModel model = createOAuthClient(rep.getId(), rep.getName(), realm);
model.updateIdentityProviders(toModel(rep.getIdentityProviders(), realm));
- updateOAuthClient(rep, model);
+ updateOAuthClient(session, rep, model);
return model;
}
- public static void updateOAuthClient(OAuthClientRepresentation rep, OAuthClientModel model) {
+ public static void updateOAuthClient(KeycloakSession session, OAuthClientRepresentation rep, OAuthClientModel model) {
+ if (rep.getProtocolMappers() == null) {
+ List<ProtocolMapperRepresentation> convertedProtocolMappers = convertDeprecatedClaimsMask(session, rep.getClaims());
+ if (convertedProtocolMappers != null) {
+ rep.setProtocolMappers(convertedProtocolMappers);
+ }
+ }
+
if (rep.getName() != null) model.setClientId(rep.getName());
if (rep.isEnabled() != null) model.setEnabled(rep.isEnabled());
if (rep.isPublicClient() != null) model.setPublicClient(rep.isPublicClient());
if (rep.isFrontchannelLogout() != null) model.setFrontchannelLogout(rep.isFrontchannelLogout());
if (rep.isFullScopeAllowed() != null) model.setFullScopeAllowed(rep.isFullScopeAllowed());
if (rep.isDirectGrantsOnly() != null) model.setDirectGrantsOnly(rep.isDirectGrantsOnly());
- if (rep.getClaims() != null) {
- setClaims(model, rep.getClaims());
- }
if (rep.getNotBefore() != null) {
model.setNotBefore(rep.getNotBefore());
}
diff --git a/model/api/src/main/resources/META-INF/services/org.keycloak.provider.Spi b/model/api/src/main/resources/META-INF/services/org.keycloak.provider.Spi
index e071894..64dd861 100755
--- a/model/api/src/main/resources/META-INF/services/org.keycloak.provider.Spi
+++ b/model/api/src/main/resources/META-INF/services/org.keycloak.provider.Spi
@@ -1,4 +1,5 @@
org.keycloak.models.UserFederationSpi
org.keycloak.models.RealmSpi
org.keycloak.models.UserSessionSpi
-org.keycloak.models.UserSpi
\ No newline at end of file
+org.keycloak.models.UserSpi
+org.keycloak.migration.MigrationSpi
\ No newline at end of file
diff --git a/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java b/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java
index c7ef8ad..6c47bdf 100755
--- a/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java
+++ b/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java
@@ -70,16 +70,6 @@ public abstract class ClientAdapter implements ClientModel {
}
@Override
- public long getAllowedClaimsMask() {
- return clientEntity.getAllowedClaimsMask();
- }
-
- @Override
- public void setAllowedClaimsMask(long mask) {
- clientEntity.setAllowedClaimsMask(mask);
- }
-
- @Override
public Set<String> getWebOrigins() {
Set<String> result = new HashSet<String>();
if (clientEntity.getWebOrigins() != null) {
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java
index 202be7b..12e89e1 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java
@@ -44,16 +44,6 @@ public abstract class ClientAdapter implements ClientModel {
@Override
public abstract String getClientId();
- public long getAllowedClaimsMask() {
- if (updatedClient != null) return updatedClient.getAllowedClaimsMask();
- return cachedClient.getAllowedClaimsMask();
- }
-
- public void setAllowedClaimsMask(long mask) {
- getDelegateForUpdate();
- updatedClient.setAllowedClaimsMask(mask);
- }
-
public Set<String> getWebOrigins() {
if (updatedClient != null) return updatedClient.getWebOrigins();
return cachedClient.getWebOrigins();
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedClient.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedClient.java
index 859e593..f1f5ef1 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedClient.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedClient.java
@@ -23,7 +23,6 @@ public class CachedClient {
protected String id;
protected String name;
protected String realm;
- protected long allowedClaimsMask;
protected Set<String> redirectUris = new HashSet<String>();
protected boolean enabled;
protected String secret;
@@ -51,7 +50,6 @@ public class CachedClient {
directGrantsOnly = model.isDirectGrantsOnly();
frontchannelLogout = model.isFrontchannelLogout();
publicClient = model.isPublicClient();
- allowedClaimsMask = model.getAllowedClaimsMask();
fullScopeAllowed = model.isFullScopeAllowed();
redirectUris.addAll(model.getRedirectUris());
webOrigins.addAll(model.getWebOrigins());
@@ -76,10 +74,6 @@ public class CachedClient {
return realm;
}
- public long getAllowedClaimsMask() {
- return allowedClaimsMask;
- }
-
public Set<String> getRedirectUris() {
return redirectUris;
}
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/MemoryUserCache.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/MemoryUserCache.java
index 360a02d..dcbf2c9 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/MemoryUserCache.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/MemoryUserCache.java
@@ -25,7 +25,9 @@ public class MemoryUserCache implements UserCache {
@Override
public CachedUser put(String key, CachedUser value) {
- usersByUsername.put(value.getUsername(), value);
+ if (value.getUsername() != null) {
+ usersByUsername.put(value.getUsername(), value);
+ }
if (value.getEmail() != null) {
usersByEmail.put(value.getEmail(), value);
}
@@ -57,7 +59,7 @@ public class MemoryUserCache implements UserCache {
}
private void removeUser(CachedUser value) {
- usersByUsername.remove(value.getUsername());
+ if (value.getUsername() != null) usersByUsername.remove(value.getUsername());
if (value.getEmail() != null) usersByEmail.remove(value.getEmail());
}
}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
index bf0fefc..bd44308 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
@@ -73,16 +73,6 @@ public abstract class ClientAdapter implements ClientModel {
}
@Override
- public long getAllowedClaimsMask() {
- return entity.getAllowedClaimsMask();
- }
-
- @Override
- public void setAllowedClaimsMask(long mask) {
- entity.setAllowedClaimsMask(mask);
- }
-
- @Override
public boolean isPublicClient() {
return entity.isPublicClient();
}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java
index f61f7bf..e3c8bfd 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java
@@ -40,8 +40,6 @@ public abstract class ClientEntity {
private boolean enabled;
@Column(name="SECRET")
private String secret;
- @Column(name="ALLOWED_CLAIMS_MASK")
- private long allowedClaimsMask;
@Column(name="NOT_BEFORE")
private int notBefore;
@Column(name="PUBLIC_CLIENT")
@@ -111,14 +109,6 @@ public abstract class ClientEntity {
this.name = name;
}
- public long getAllowedClaimsMask() {
- return allowedClaimsMask;
- }
-
- public void setAllowedClaimsMask(long allowedClaimsMask) {
- this.allowedClaimsMask = allowedClaimsMask;
- }
-
public Set<String> getWebOrigins() {
return webOrigins;
}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
index ea97d65..38c40f8 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
@@ -60,17 +60,6 @@ public abstract class ClientAdapter<T extends MongoIdentifiableEntity> extends A
}
@Override
- public long getAllowedClaimsMask() {
- return getMongoEntityAsClient().getAllowedClaimsMask();
- }
-
- @Override
- public void setAllowedClaimsMask(long mask) {
- getMongoEntityAsClient().setAllowedClaimsMask(mask);
- updateMongoEntity();
- }
-
- @Override
public Set<String> getWebOrigins() {
Set<String> result = new HashSet<String>();
if (getMongoEntityAsClient().getWebOrigins() != null) {
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java
index dd06346..66197b7 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java
@@ -223,6 +223,7 @@ public class AuthorizationEndpoint {
clientSession.setNote(ClientSessionCode.ACTION_KEY, KeycloakModelUtils.generateCodeSecret());
clientSession.setNote(OIDCLoginProtocol.RESPONSE_TYPE_PARAM, responseType);
clientSession.setNote(OIDCLoginProtocol.REDIRECT_URI_PARAM, redirectUriParam);
+ clientSession.setNote(OIDCLoginProtocol.ISSUER, Urls.realmIssuer(uriInfo.getBaseUri(), realm.getName()));
if (state != null) clientSession.setNote(OIDCLoginProtocol.STATE_PARAM, state);
if (scope != null) clientSession.setNote(OIDCLoginProtocol.SCOPE_PARAM, scope);
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 d796f8f..bd211e4 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
@@ -29,6 +29,7 @@ import org.keycloak.services.ErrorResponseException;
import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.managers.ClientSessionCode;
import org.keycloak.services.resources.Cors;
+import org.keycloak.services.resources.flows.Urls;
import javax.ws.rs.Consumes;
import javax.ws.rs.OPTIONS;
@@ -319,6 +320,7 @@ public class TokenEndpoint {
ClientSessionModel clientSession = sessions.createClientSession(realm, client);
clientSession.setAuthMethod(OIDCLoginProtocol.LOGIN_PROTOCOL);
+ clientSession.setNote(OIDCLoginProtocol.ISSUER, Urls.realmIssuer(uriInfo.getBaseUri(), realm.getName()));
TokenManager.attachClientSession(userSession, clientSession);
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/UserInfoEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/UserInfoEndpoint.java
index 1e6fc26..b41e972 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/UserInfoEndpoint.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/UserInfoEndpoint.java
@@ -39,6 +39,7 @@ import org.keycloak.services.managers.AppAuthManager;
import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.managers.EventsManager;
import org.keycloak.services.resources.Cors;
+import org.keycloak.services.resources.flows.Urls;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
@@ -52,6 +53,7 @@ import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
+import javax.ws.rs.core.UriInfo;
import java.util.HashMap;
import java.util.Map;
@@ -67,6 +69,9 @@ public class UserInfoEndpoint {
private HttpResponse response;
@Context
+ private UriInfo uriInfo;
+
+ @Context
private KeycloakSession session;
@Context
@@ -114,7 +119,7 @@ public class UserInfoEndpoint {
AccessToken token = null;
try {
- token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), realm.getName());
+ token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), Urls.realmIssuer(uriInfo.getBaseUri(), realm.getName()));
} catch (Exception e) {
throw new ErrorResponseException(OAuthErrorException.INVALID_GRANT, "Token invalid", Status.FORBIDDEN);
}
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/ValidateTokenEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/ValidateTokenEndpoint.java
index 8dad6fd..31499d1 100644
--- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/ValidateTokenEndpoint.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/ValidateTokenEndpoint.java
@@ -15,6 +15,7 @@ import org.keycloak.models.RealmModel;
import org.keycloak.protocol.oidc.TokenManager;
import org.keycloak.representations.AccessToken;
import org.keycloak.services.ErrorResponseException;
+import org.keycloak.services.resources.flows.Urls;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
@@ -68,7 +69,7 @@ public class ValidateTokenEndpoint {
event.event(EventType.VALIDATE_ACCESS_TOKEN);
AccessToken token = null;
try {
- token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), realm.getName());
+ token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), Urls.realmIssuer(uriInfo.getBaseUri(), realm.getName()));
} catch (Exception e) {
Map<String, String> err = new HashMap<String, String>();
err.put(OAuth2Constants.ERROR, OAuthErrorException.INVALID_GRANT);
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java
index 022b6ac..5815037 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java
@@ -59,6 +59,7 @@ public class OIDCLoginProtocol implements LoginProtocol {
public static final String PROMPT_PARAM = "prompt";
public static final String LOGIN_HINT_PARAM = "login_hint";
public static final String LOGOUT_REDIRECT_URI = "OIDC_LOGOUT_REDIRECT_URI";
+ public static final String ISSUER = "iss";
private static final Logger log = Logger.getLogger(OIDCLoginProtocol.class);
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java b/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java
index 01e244c..e21d091 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java
@@ -314,7 +314,7 @@ public class TokenManager {
token.audience(client.getClientId());
token.issuedNow();
token.issuedFor(client.getClientId());
- token.issuer(realm.getName());
+ token.issuer(clientSession.getNote(OIDCLoginProtocol.ISSUER));
if (session != null) {
token.setSessionState(session.getId());
}
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 bdc583a..f8b9bb2 100755
--- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
@@ -32,6 +32,7 @@ import org.keycloak.services.resources.IdentityBrokerService;
import org.keycloak.services.resources.LoginActionsService;
import org.keycloak.services.resources.RealmsResource;
import org.keycloak.services.resources.flows.Flows;
+import org.keycloak.services.resources.flows.Urls;
import org.keycloak.services.util.CookieHelper;
import org.keycloak.services.validation.Validation;
import org.keycloak.util.Time;
@@ -192,12 +193,12 @@ public class AuthenticationManager {
}
- public static AccessToken createIdentityToken(RealmModel realm, UserModel user, UserSessionModel session) {
+ public static AccessToken createIdentityToken(RealmModel realm, UserModel user, UserSessionModel session, String issuer) {
AccessToken token = new AccessToken();
token.id(KeycloakModelUtils.generateId());
token.issuedNow();
token.subject(user.getId());
- token.issuer(realm.getName());
+ token.issuer(issuer);
if (session != null) {
token.setSessionState(session.getId());
}
@@ -209,7 +210,8 @@ public class AuthenticationManager {
public static void createLoginCookie(RealmModel realm, UserModel user, UserSessionModel session, UriInfo uriInfo, ClientConnection connection) {
String cookiePath = getIdentityCookiePath(realm, uriInfo);
- AccessToken identityToken = createIdentityToken(realm, user, session);
+ String issuer = Urls.realmIssuer(uriInfo.getBaseUri(), realm.getName());
+ AccessToken identityToken = createIdentityToken(realm, user, session, issuer);
String encoded = encodeToken(realm, identityToken);
boolean secureOnly = realm.getSslRequired().isRequired(connection);
int maxAge = NewCookie.DEFAULT_MAX_AGE;
@@ -443,7 +445,7 @@ public class AuthenticationManager {
protected AuthResult verifyIdentityToken(KeycloakSession session, RealmModel realm, UriInfo uriInfo, ClientConnection connection, boolean checkActive, String tokenString, HttpHeaders headers) {
try {
- AccessToken token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), realm.getName(), checkActive);
+ AccessToken token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), Urls.realmIssuer(uriInfo.getBaseUri(), realm.getName()), checkActive);
if (checkActive) {
if (!token.isActive() || token.getIssuedAt() < realm.getNotBefore()) {
logger.debug("identity cookie expired");
diff --git a/services/src/main/java/org/keycloak/services/migration/DefaultMigrationProviderFactory.java b/services/src/main/java/org/keycloak/services/migration/DefaultMigrationProviderFactory.java
new file mode 100644
index 0000000..cdc9f93
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/migration/DefaultMigrationProviderFactory.java
@@ -0,0 +1,38 @@
+package org.keycloak.services.migration;
+
+import org.keycloak.Config;
+import org.keycloak.migration.MigrationProvider;
+import org.keycloak.migration.MigrationProviderFactory;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionFactory;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class DefaultMigrationProviderFactory implements MigrationProviderFactory {
+
+ @Override
+ public MigrationProvider create(KeycloakSession session) {
+ return new DefaultMigrationProvider(session);
+ }
+
+ @Override
+ public void init(Config.Scope config) {
+
+ }
+
+ @Override
+ public void postInit(KeycloakSessionFactory factory) {
+
+ }
+
+ @Override
+ public void close() {
+
+ }
+
+ @Override
+ public String getId() {
+ return "default";
+ }
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java b/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java
index 8368fc3..4ecdbab 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java
@@ -140,7 +140,7 @@ public class AdminRoot {
} catch (IOException e) {
throw new UnauthorizedException("Bearer token format error");
}
- String realmName = token.getIssuer();
+ String realmName = token.getIssuer().substring(token.getIssuer().lastIndexOf('/') + 1);
RealmManager realmManager = new RealmManager(session);
RealmModel realm = realmManager.getRealmByName(realmName);
if (realm == null) {
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
index cc996cd..7df7b1e 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
@@ -78,16 +78,6 @@ public class ApplicationResource {
auth.init(RealmAuth.Resource.APPLICATION);
}
- /**
- * base path for managing allowed application claims
- *
- * @return
- */
- @Path("claims")
- public ClaimResource getClaimResource() {
- return new ClaimResource(application, auth);
- }
-
@Path("protocol-mappers")
public ProtocolMappersResource getProtocolMappers() {
ProtocolMappersResource mappers = new ProtocolMappersResource(application, auth);
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java
index e47e002..c74a8f0 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java
@@ -87,7 +87,7 @@ public class ApplicationsResource {
auth.requireManage();
try {
- ApplicationModel applicationModel = RepresentationToModel.createApplication(realm, rep, true);
+ ApplicationModel applicationModel = RepresentationToModel.createApplication(session, realm, rep, true);
return Response.created(uriInfo.getAbsolutePathBuilder().path(getApplicationPath(applicationModel)).build()).build();
} catch (ModelDuplicateException e) {
return Flows.errors().exists("Application " + rep.getName() + " already exists");
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java
index 10b20b8..b69fb83 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java
@@ -65,16 +65,6 @@ public class OAuthClientResource {
}
/**
- * Base path for managing allowed oauth client claims
- *
- * @return
- */
- @Path("claims")
- public ClaimResource getClaimResource() {
- return new ClaimResource(oauthClient, auth);
- }
-
- /**
* interface for updating attached ProtocolMappers
*
* @return
@@ -111,7 +101,7 @@ public class OAuthClientResource {
auth.requireManage();
try {
- RepresentationToModel.updateOAuthClient(rep, oauthClient);
+ RepresentationToModel.updateOAuthClient(session, rep, oauthClient);
return Response.noContent().build();
} catch (ModelDuplicateException e) {
return Flows.errors().exists("Client " + rep.getName() + " already exists");
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java
index 3d57d42..a2c387c 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java
@@ -89,7 +89,7 @@ public class OAuthClientsResource {
auth.requireManage();
try {
- OAuthClientModel oauth = RepresentationToModel.createOAuthClient(rep, realm);
+ OAuthClientModel oauth = RepresentationToModel.createOAuthClient(session, rep, realm);
return Response.created(uriInfo.getAbsolutePathBuilder().path(getClientPath(oauth)).build()).build();
} catch (ModelDuplicateException e) {
return Flows.errors().exists("Client " + rep.getName() + " already exists");
diff --git a/services/src/main/java/org/keycloak/services/resources/flows/Urls.java b/services/src/main/java/org/keycloak/services/resources/flows/Urls.java
index a214f62..bb3b078 100755
--- a/services/src/main/java/org/keycloak/services/resources/flows/Urls.java
+++ b/services/src/main/java/org/keycloak/services/resources/flows/Urls.java
@@ -158,6 +158,10 @@ public class Urls {
return requiredActionsBase(baseUri).path(LoginActionsService.class, "usernameReminder");
}
+ public static String realmIssuer(URI baseUri, String realmId) {
+ return realmBase(baseUri).path("{realm}").build(realmId).toString();
+ }
+
private static UriBuilder realmBase(URI baseUri) {
return UriBuilder.fromUri(baseUri).path(RealmsResource.class);
}
diff --git a/services/src/main/resources/META-INF/services/org.keycloak.migration.MigrationProviderFactory b/services/src/main/resources/META-INF/services/org.keycloak.migration.MigrationProviderFactory
new file mode 100644
index 0000000..d928feb
--- /dev/null
+++ b/services/src/main/resources/META-INF/services/org.keycloak.migration.MigrationProviderFactory
@@ -0,0 +1 @@
+org.keycloak.services.migration.DefaultMigrationProviderFactory
\ No newline at end of file
diff --git a/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java b/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java
index 772cd5a..a57f317 100755
--- a/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java
+++ b/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java
@@ -53,19 +53,6 @@ import java.util.Properties;
*/
public class KeycloakServer {
- static {
- try {
- File f = new File(System.getProperty("user.home"), ".keycloak-test.properties");
- if (f.isFile()) {
- Properties p = new Properties();
- p.load(new FileInputStream(f));
- System.getProperties().putAll(p);
- }
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
private static final Logger log = Logger.getLogger(KeycloakServer.class);
private boolean sysout = false;
@@ -122,6 +109,13 @@ public class KeycloakServer {
}
public static KeycloakServer bootstrapKeycloakServer(String[] args) throws Throwable {
+ File f = new File(System.getProperty("user.home"), ".keycloak-server.properties");
+ if (f.isFile()) {
+ Properties p = new Properties();
+ p.load(new FileInputStream(f));
+ System.getProperties().putAll(p);
+ }
+
KeycloakServerConfig config = new KeycloakServerConfig();
for (int i = 0; i < args.length; i++) {
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 00b071e..ce61d33 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
@@ -1,471 +1,471 @@
-/*
- * 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.account;
-
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Ignore;
-import org.junit.Rule;
-import org.junit.Test;
-import org.keycloak.events.Details;
-import org.keycloak.events.Event;
-import org.keycloak.events.EventType;
-import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.PasswordPolicy;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.UserCredentialModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.models.utils.TimeBasedOTP;
-import org.keycloak.representations.idm.CredentialRepresentation;
-import org.keycloak.services.managers.RealmManager;
-import org.keycloak.services.resources.AccountService;
-import org.keycloak.services.resources.RealmsResource;
-import org.keycloak.testsuite.AssertEvents;
-import org.keycloak.testsuite.OAuthClient;
-import org.keycloak.testsuite.pages.AccountLogPage;
-import org.keycloak.testsuite.pages.AccountPasswordPage;
-import org.keycloak.testsuite.pages.AccountSessionsPage;
-import org.keycloak.testsuite.pages.AccountTotpPage;
-import org.keycloak.testsuite.pages.AccountUpdateProfilePage;
-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.RegisterPage;
-import org.keycloak.testsuite.rule.KeycloakRule;
-import org.keycloak.testsuite.rule.KeycloakRule.KeycloakSetup;
-import org.keycloak.testsuite.rule.WebResource;
-import org.keycloak.testsuite.rule.WebRule;
-import org.openqa.selenium.By;
-import org.openqa.selenium.WebDriver;
-
-import javax.ws.rs.core.UriBuilder;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
- */
-public class AccountTest {
-
- @ClassRule
- public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakSetup() {
- @Override
- public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
-
- ApplicationModel accountApp = appRealm.getApplicationNameMap().get(org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_APP);
-
- UserModel user2 = manager.getSession().users().addUser(appRealm, "test-user-no-access@localhost");
- user2.setEnabled(true);
- for (String r : accountApp.getDefaultRoles()) {
- user2.deleteRoleMapping(accountApp.getRole(r));
- }
- UserCredentialModel creds = new UserCredentialModel();
- creds.setType(CredentialRepresentation.PASSWORD);
- creds.setValue("password");
- user2.updateCredential(creds);
- }
- });
-
- private static final UriBuilder BASE = UriBuilder.fromUri("http://localhost:8081/auth");
- private static final String ACCOUNT_URL = RealmsResource.accountUrl(BASE.clone()).build("test").toString();
- public static String ACCOUNT_REDIRECT = AccountService.loginRedirectUrl(BASE.clone()).build("test").toString();
-
- @Rule
- public AssertEvents events = new AssertEvents(keycloakRule);
-
- @Rule
- public WebRule webRule = new WebRule(this);
-
- @WebResource
- protected WebDriver driver;
-
- @WebResource
- protected OAuthClient oauth;
-
- @WebResource
- protected AppPage appPage;
-
- @WebResource
- protected LoginPage loginPage;
-
- @WebResource
- protected RegisterPage registerPage;
-
- @WebResource
- protected AccountPasswordPage changePasswordPage;
-
- @WebResource
- protected AccountUpdateProfilePage profilePage;
-
- @WebResource
- protected AccountTotpPage totpPage;
-
- @WebResource
- protected AccountLogPage logPage;
-
- @WebResource
- protected AccountSessionsPage sessionsPage;
-
- @WebResource
- protected ErrorPage errorPage;
-
- private TimeBasedOTP totp = new TimeBasedOTP();
- private String userId;
-
- @Before
- public void before() {
- oauth.state("mystate"); // keycloak enforces that a state param has been sent by client
- userId = keycloakRule.getUser("test", "test-user@localhost").getId();
- }
-
- @After
- public void after() {
- keycloakRule.update(new KeycloakSetup() {
- @Override
- public void config(RealmManager manager, RealmModel defaultRealm, RealmModel appRealm) {
- UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
-
- UserCredentialModel cred = new UserCredentialModel();
- cred.setType(CredentialRepresentation.PASSWORD);
- cred.setValue("password");
-
- user.updateCredential(cred);
- }
- });
- }
-
- @Test @Ignore
- public void runit() throws Exception {
- Thread.sleep(10000000);
- }
-
- @Test
- public void returnToAppFromQueryParam() {
- driver.navigate().to(AccountUpdateProfilePage.PATH + "?referrer=test-app");
- loginPage.login("test-user@localhost", "password");
- Assert.assertTrue(profilePage.isCurrent());
- profilePage.backToApplication();
-
- Assert.assertTrue(appPage.isCurrent());
-
- driver.navigate().to(AccountUpdateProfilePage.PATH + "?referrer=test-app&referrer_uri=http://localhost:8081/app?test");
- Assert.assertTrue(profilePage.isCurrent());
- profilePage.backToApplication();
-
- Assert.assertTrue(appPage.isCurrent());
- Assert.assertEquals(appPage.baseUrl + "?test", driver.getCurrentUrl());
-
- driver.navigate().to(AccountUpdateProfilePage.PATH + "?referrer=test-app");
- Assert.assertTrue(profilePage.isCurrent());
-
- driver.findElement(By.linkText("Authenticator")).click();
- Assert.assertTrue(totpPage.isCurrent());
-
- driver.findElement(By.linkText("Account")).click();
- Assert.assertTrue(profilePage.isCurrent());
-
- profilePage.backToApplication();
-
- Assert.assertTrue(appPage.isCurrent());
-
- events.clear();
- }
-
- @Test
- public void changePassword() {
- changePasswordPage.open();
- loginPage.login("test-user@localhost", "password");
-
- String sessionId = events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent().getSessionId();
-
- changePasswordPage.changePassword("", "new-password", "new-password");
-
- Assert.assertEquals("Please specify password.", profilePage.getError());
-
- changePasswordPage.changePassword("password", "new-password", "new-password2");
-
- Assert.assertEquals("Password confirmation doesn't match.", profilePage.getError());
-
- changePasswordPage.changePassword("password", "new-password", "new-password");
-
- Assert.assertEquals("Your password has been updated.", profilePage.getSuccess());
-
- events.expectAccount(EventType.UPDATE_PASSWORD).assertEvent();
-
- changePasswordPage.logout();
-
- events.expectLogout(sessionId).detail(Details.REDIRECT_URI, changePasswordPage.getPath()).assertEvent();
-
- loginPage.open();
- loginPage.login("test-user@localhost", "password");
-
- Assert.assertEquals("Invalid username or password.", loginPage.getError());
-
- events.expectLogin().session((String) null).error("invalid_user_credentials").assertEvent();
-
- loginPage.open();
- loginPage.login("test-user@localhost", "new-password");
-
- Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
-
- events.expectLogin().assertEvent();
- }
-
- @Test
- public void changePasswordWithPasswordPolicy() {
- keycloakRule.update(new KeycloakRule.KeycloakSetup() {
- @Override
- public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- appRealm.setPasswordPolicy(new PasswordPolicy("length"));
- }
- });
-
- try {
- changePasswordPage.open();
- loginPage.login("test-user@localhost", "password");
-
-
- events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent();
-
- changePasswordPage.changePassword("", "new", "new");
-
- Assert.assertEquals("Please specify password.", profilePage.getError());
-
- changePasswordPage.changePassword("password", "new-password", "new-password");
-
- Assert.assertEquals("Your password has been updated.", profilePage.getSuccess());
-
- events.expectAccount(EventType.UPDATE_PASSWORD).assertEvent();
- } finally {
- keycloakRule.update(new KeycloakRule.KeycloakSetup() {
- @Override
- public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- appRealm.setPasswordPolicy(new PasswordPolicy(null));
- }
- });
- }
- }
-
- @Test
- public void changeProfile() {
- profilePage.open();
- loginPage.login("test-user@localhost", "password");
-
- events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT).assertEvent();
-
- Assert.assertEquals("Tom", profilePage.getFirstName());
- Assert.assertEquals("Brady", profilePage.getLastName());
- Assert.assertEquals("test-user@localhost", profilePage.getEmail());
-
- // All fields are required, so there should be an error when something is missing.
- profilePage.updateProfile("", "New last", "new@email.com");
-
- Assert.assertEquals("Please specify first name.", profilePage.getError());
- Assert.assertEquals("", profilePage.getFirstName());
- Assert.assertEquals("New last", profilePage.getLastName());
- Assert.assertEquals("new@email.com", profilePage.getEmail());
-
- events.assertEmpty();
-
- profilePage.updateProfile("New first", "", "new@email.com");
-
- Assert.assertEquals("Please specify last name.", profilePage.getError());
- Assert.assertEquals("New first", profilePage.getFirstName());
- Assert.assertEquals("", profilePage.getLastName());
- Assert.assertEquals("new@email.com", profilePage.getEmail());
-
- events.assertEmpty();
-
- profilePage.updateProfile("New first", "New last", "");
-
- Assert.assertEquals("Please specify email.", profilePage.getError());
- Assert.assertEquals("New first", profilePage.getFirstName());
- Assert.assertEquals("New last", profilePage.getLastName());
- Assert.assertEquals("", profilePage.getEmail());
-
- events.assertEmpty();
-
- profilePage.clickCancel();
-
- Assert.assertEquals("Tom", profilePage.getFirstName());
- Assert.assertEquals("Brady", profilePage.getLastName());
- Assert.assertEquals("test-user@localhost", profilePage.getEmail());
-
- events.assertEmpty();
-
- profilePage.updateProfile("New first", "New last", "new@email.com");
-
- Assert.assertEquals("Your account has been updated.", profilePage.getSuccess());
- Assert.assertEquals("New first", profilePage.getFirstName());
- Assert.assertEquals("New last", profilePage.getLastName());
- Assert.assertEquals("new@email.com", profilePage.getEmail());
-
- events.expectAccount(EventType.UPDATE_PROFILE).assertEvent();
- events.expectAccount(EventType.UPDATE_EMAIL).detail(Details.PREVIOUS_EMAIL, "test-user@localhost").detail(Details.UPDATED_EMAIL, "new@email.com").assertEvent();
- }
-
- @Test
- public void setupTotp() {
- totpPage.open();
- loginPage.login("test-user@localhost", "password");
-
- events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=totp").assertEvent();
-
- Assert.assertTrue(totpPage.isCurrent());
-
- Assert.assertFalse(driver.getPageSource().contains("Remove Google"));
-
- // Error with false code
- totpPage.configure(totp.generate(totpPage.getTotpSecret() + "123"));
-
- Assert.assertEquals("Invalid authenticator code.", profilePage.getError());
-
- totpPage.configure(totp.generate(totpPage.getTotpSecret()));
-
- Assert.assertEquals("Mobile authenticator configured.", profilePage.getSuccess());
-
- events.expectAccount(EventType.UPDATE_TOTP).assertEvent();
-
- Assert.assertTrue(driver.getPageSource().contains("pficon-delete"));
-
- totpPage.removeTotp();
-
- events.expectAccount(EventType.REMOVE_TOTP).assertEvent();
- }
-
- @Test
- public void changeProfileNoAccess() throws Exception {
- profilePage.open();
- loginPage.login("test-user-no-access@localhost", "password");
-
- events.expectLogin().client("account").user(keycloakRule.getUser("test", "test-user-no-access@localhost").getId())
- .detail(Details.USERNAME, "test-user-no-access@localhost")
- .detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT).assertEvent();
-
- Assert.assertTrue(errorPage.isCurrent());
- Assert.assertEquals("No access", errorPage.getError());
- }
-
- @Test
- public void viewLog() {
- keycloakRule.update(new KeycloakSetup() {
- @Override
- public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- appRealm.setEventsEnabled(true);
- }
- });
-
- try {
- List<Event> expectedEvents = new LinkedList<Event>();
-
- loginPage.open();
- loginPage.clickRegister();
-
- registerPage.register("view", "log", "view-log@localhost", "view-log", "password", "password");
-
- expectedEvents.add(events.poll());
- expectedEvents.add(events.poll());
-
- profilePage.open();
- profilePage.updateProfile("view", "log2", "view-log@localhost");
-
- expectedEvents.add(events.poll());
-
- logPage.open();
-
- Assert.assertTrue(logPage.isCurrent());
-
- List<List<String>> actualEvents = logPage.getEvents();
-
- Assert.assertEquals(expectedEvents.size(), actualEvents.size());
-
- for (Event e : expectedEvents) {
- boolean match = false;
- for (List<String> a : logPage.getEvents()) {
- if (e.getType().toString().replace('_', ' ').toLowerCase().equals(a.get(1)) &&
- e.getIpAddress().equals(a.get(2)) &&
- e.getClientId().equals(a.get(3))) {
- match = true;
- break;
- }
- }
- if (!match) {
- Assert.fail("Event not found " + e.getType());
- }
- }
- } finally {
- keycloakRule.update(new KeycloakSetup() {
- @Override
- public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- appRealm.setEventsEnabled(false);
- }
- });
- }
- }
-
- @Test
- public void sessions() {
- loginPage.open();
- loginPage.clickRegister();
-
- registerPage.register("view", "sessions", "view-sessions@localhost", "view-sessions", "password", "password");
-
- Event registerEvent = events.expectRegister("view-sessions", "view-sessions@localhost").assertEvent();
- String userId = registerEvent.getUserId();
-
- events.expectLogin().user(userId).detail(Details.USERNAME, "view-sessions").assertEvent();
-
- sessionsPage.open();
-
- Assert.assertTrue(sessionsPage.isCurrent());
-
- List<List<String>> sessions = sessionsPage.getSessions();
- Assert.assertEquals(1, sessions.size());
- Assert.assertEquals("127.0.0.1", sessions.get(0).get(0));
-
- // Create second session
- WebDriver driver2 = WebRule.createWebDriver();
- try {
- OAuthClient oauth2 = new OAuthClient(driver2);
- oauth2.state("mystate");
- oauth2.doLogin("view-sessions", "password");
-
- Event login2Event = events.expectLogin().user(userId).detail(Details.USERNAME, "view-sessions").assertEvent();
-
- sessionsPage.open();
- sessions = sessionsPage.getSessions();
- Assert.assertEquals(2, sessions.size());
-
- sessionsPage.logoutAll();
-
- events.expectLogout(registerEvent.getSessionId());
- events.expectLogout(login2Event.getSessionId());
- } finally {
- driver2.close();
- }
- }
-
-}
+/*
+ * 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.account;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.keycloak.events.Details;
+import org.keycloak.events.Event;
+import org.keycloak.events.EventType;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.PasswordPolicy;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserCredentialModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.utils.TimeBasedOTP;
+import org.keycloak.representations.idm.CredentialRepresentation;
+import org.keycloak.services.managers.RealmManager;
+import org.keycloak.services.resources.AccountService;
+import org.keycloak.services.resources.RealmsResource;
+import org.keycloak.testsuite.AssertEvents;
+import org.keycloak.testsuite.OAuthClient;
+import org.keycloak.testsuite.pages.AccountLogPage;
+import org.keycloak.testsuite.pages.AccountPasswordPage;
+import org.keycloak.testsuite.pages.AccountSessionsPage;
+import org.keycloak.testsuite.pages.AccountTotpPage;
+import org.keycloak.testsuite.pages.AccountUpdateProfilePage;
+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.RegisterPage;
+import org.keycloak.testsuite.rule.KeycloakRule;
+import org.keycloak.testsuite.rule.KeycloakRule.KeycloakSetup;
+import org.keycloak.testsuite.rule.WebResource;
+import org.keycloak.testsuite.rule.WebRule;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+
+import javax.ws.rs.core.UriBuilder;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class AccountTest {
+
+ @ClassRule
+ public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakSetup() {
+ @Override
+ public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+ UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
+
+ ApplicationModel accountApp = appRealm.getApplicationNameMap().get(org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_APP);
+
+ UserModel user2 = manager.getSession().users().addUser(appRealm, "test-user-no-access@localhost");
+ user2.setEnabled(true);
+ for (String r : accountApp.getDefaultRoles()) {
+ user2.deleteRoleMapping(accountApp.getRole(r));
+ }
+ UserCredentialModel creds = new UserCredentialModel();
+ creds.setType(CredentialRepresentation.PASSWORD);
+ creds.setValue("password");
+ user2.updateCredential(creds);
+ }
+ });
+
+ private static final UriBuilder BASE = UriBuilder.fromUri("http://localhost:8081/auth");
+ private static final String ACCOUNT_URL = RealmsResource.accountUrl(BASE.clone()).build("test").toString();
+ public static String ACCOUNT_REDIRECT = AccountService.loginRedirectUrl(BASE.clone()).build("test").toString();
+
+ @Rule
+ public AssertEvents events = new AssertEvents(keycloakRule);
+
+ @Rule
+ public WebRule webRule = new WebRule(this);
+
+ @WebResource
+ protected WebDriver driver;
+
+ @WebResource
+ protected OAuthClient oauth;
+
+ @WebResource
+ protected AppPage appPage;
+
+ @WebResource
+ protected LoginPage loginPage;
+
+ @WebResource
+ protected RegisterPage registerPage;
+
+ @WebResource
+ protected AccountPasswordPage changePasswordPage;
+
+ @WebResource
+ protected AccountUpdateProfilePage profilePage;
+
+ @WebResource
+ protected AccountTotpPage totpPage;
+
+ @WebResource
+ protected AccountLogPage logPage;
+
+ @WebResource
+ protected AccountSessionsPage sessionsPage;
+
+ @WebResource
+ protected ErrorPage errorPage;
+
+ private TimeBasedOTP totp = new TimeBasedOTP();
+ private String userId;
+
+ @Before
+ public void before() {
+ oauth.state("mystate"); // keycloak enforces that a state param has been sent by client
+ userId = keycloakRule.getUser("test", "test-user@localhost").getId();
+ }
+
+ @After
+ public void after() {
+ keycloakRule.update(new KeycloakSetup() {
+ @Override
+ public void config(RealmManager manager, RealmModel defaultRealm, RealmModel appRealm) {
+ UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
+
+ UserCredentialModel cred = new UserCredentialModel();
+ cred.setType(CredentialRepresentation.PASSWORD);
+ cred.setValue("password");
+
+ user.updateCredential(cred);
+ }
+ });
+ }
+
+ //@Test @Ignore
+ public void runit() throws Exception {
+ Thread.sleep(10000000);
+ }
+
+ @Test
+ public void returnToAppFromQueryParam() {
+ driver.navigate().to(AccountUpdateProfilePage.PATH + "?referrer=test-app");
+ loginPage.login("test-user@localhost", "password");
+ Assert.assertTrue(profilePage.isCurrent());
+ profilePage.backToApplication();
+
+ Assert.assertTrue(appPage.isCurrent());
+
+ driver.navigate().to(AccountUpdateProfilePage.PATH + "?referrer=test-app&referrer_uri=http://localhost:8081/app?test");
+ Assert.assertTrue(profilePage.isCurrent());
+ profilePage.backToApplication();
+
+ Assert.assertTrue(appPage.isCurrent());
+ Assert.assertEquals(appPage.baseUrl + "?test", driver.getCurrentUrl());
+
+ driver.navigate().to(AccountUpdateProfilePage.PATH + "?referrer=test-app");
+ Assert.assertTrue(profilePage.isCurrent());
+
+ driver.findElement(By.linkText("Authenticator")).click();
+ Assert.assertTrue(totpPage.isCurrent());
+
+ driver.findElement(By.linkText("Account")).click();
+ Assert.assertTrue(profilePage.isCurrent());
+
+ profilePage.backToApplication();
+
+ Assert.assertTrue(appPage.isCurrent());
+
+ events.clear();
+ }
+
+ @Test
+ public void changePassword() {
+ changePasswordPage.open();
+ loginPage.login("test-user@localhost", "password");
+
+ String sessionId = events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent().getSessionId();
+
+ changePasswordPage.changePassword("", "new-password", "new-password");
+
+ Assert.assertEquals("Please specify password.", profilePage.getError());
+
+ changePasswordPage.changePassword("password", "new-password", "new-password2");
+
+ Assert.assertEquals("Password confirmation doesn't match.", profilePage.getError());
+
+ changePasswordPage.changePassword("password", "new-password", "new-password");
+
+ Assert.assertEquals("Your password has been updated.", profilePage.getSuccess());
+
+ events.expectAccount(EventType.UPDATE_PASSWORD).assertEvent();
+
+ changePasswordPage.logout();
+
+ events.expectLogout(sessionId).detail(Details.REDIRECT_URI, changePasswordPage.getPath()).assertEvent();
+
+ loginPage.open();
+ loginPage.login("test-user@localhost", "password");
+
+ Assert.assertEquals("Invalid username or password.", loginPage.getError());
+
+ events.expectLogin().session((String) null).error("invalid_user_credentials").assertEvent();
+
+ loginPage.open();
+ loginPage.login("test-user@localhost", "new-password");
+
+ Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
+
+ events.expectLogin().assertEvent();
+ }
+
+ @Test
+ public void changePasswordWithPasswordPolicy() {
+ keycloakRule.update(new KeycloakRule.KeycloakSetup() {
+ @Override
+ public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+ appRealm.setPasswordPolicy(new PasswordPolicy("length"));
+ }
+ });
+
+ try {
+ changePasswordPage.open();
+ loginPage.login("test-user@localhost", "password");
+
+
+ events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent();
+
+ changePasswordPage.changePassword("", "new", "new");
+
+ Assert.assertEquals("Please specify password.", profilePage.getError());
+
+ changePasswordPage.changePassword("password", "new-password", "new-password");
+
+ Assert.assertEquals("Your password has been updated.", profilePage.getSuccess());
+
+ events.expectAccount(EventType.UPDATE_PASSWORD).assertEvent();
+ } finally {
+ keycloakRule.update(new KeycloakRule.KeycloakSetup() {
+ @Override
+ public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+ appRealm.setPasswordPolicy(new PasswordPolicy(null));
+ }
+ });
+ }
+ }
+
+ @Test
+ public void changeProfile() {
+ profilePage.open();
+ loginPage.login("test-user@localhost", "password");
+
+ events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT).assertEvent();
+
+ Assert.assertEquals("Tom", profilePage.getFirstName());
+ Assert.assertEquals("Brady", profilePage.getLastName());
+ Assert.assertEquals("test-user@localhost", profilePage.getEmail());
+
+ // All fields are required, so there should be an error when something is missing.
+ profilePage.updateProfile("", "New last", "new@email.com");
+
+ Assert.assertEquals("Please specify first name.", profilePage.getError());
+ Assert.assertEquals("", profilePage.getFirstName());
+ Assert.assertEquals("New last", profilePage.getLastName());
+ Assert.assertEquals("new@email.com", profilePage.getEmail());
+
+ events.assertEmpty();
+
+ profilePage.updateProfile("New first", "", "new@email.com");
+
+ Assert.assertEquals("Please specify last name.", profilePage.getError());
+ Assert.assertEquals("New first", profilePage.getFirstName());
+ Assert.assertEquals("", profilePage.getLastName());
+ Assert.assertEquals("new@email.com", profilePage.getEmail());
+
+ events.assertEmpty();
+
+ profilePage.updateProfile("New first", "New last", "");
+
+ Assert.assertEquals("Please specify email.", profilePage.getError());
+ Assert.assertEquals("New first", profilePage.getFirstName());
+ Assert.assertEquals("New last", profilePage.getLastName());
+ Assert.assertEquals("", profilePage.getEmail());
+
+ events.assertEmpty();
+
+ profilePage.clickCancel();
+
+ Assert.assertEquals("Tom", profilePage.getFirstName());
+ Assert.assertEquals("Brady", profilePage.getLastName());
+ Assert.assertEquals("test-user@localhost", profilePage.getEmail());
+
+ events.assertEmpty();
+
+ profilePage.updateProfile("New first", "New last", "new@email.com");
+
+ Assert.assertEquals("Your account has been updated.", profilePage.getSuccess());
+ Assert.assertEquals("New first", profilePage.getFirstName());
+ Assert.assertEquals("New last", profilePage.getLastName());
+ Assert.assertEquals("new@email.com", profilePage.getEmail());
+
+ events.expectAccount(EventType.UPDATE_PROFILE).assertEvent();
+ events.expectAccount(EventType.UPDATE_EMAIL).detail(Details.PREVIOUS_EMAIL, "test-user@localhost").detail(Details.UPDATED_EMAIL, "new@email.com").assertEvent();
+ }
+
+ @Test
+ public void setupTotp() {
+ totpPage.open();
+ loginPage.login("test-user@localhost", "password");
+
+ events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=totp").assertEvent();
+
+ Assert.assertTrue(totpPage.isCurrent());
+
+ Assert.assertFalse(driver.getPageSource().contains("Remove Google"));
+
+ // Error with false code
+ totpPage.configure(totp.generate(totpPage.getTotpSecret() + "123"));
+
+ Assert.assertEquals("Invalid authenticator code.", profilePage.getError());
+
+ totpPage.configure(totp.generate(totpPage.getTotpSecret()));
+
+ Assert.assertEquals("Mobile authenticator configured.", profilePage.getSuccess());
+
+ events.expectAccount(EventType.UPDATE_TOTP).assertEvent();
+
+ Assert.assertTrue(driver.getPageSource().contains("pficon-delete"));
+
+ totpPage.removeTotp();
+
+ events.expectAccount(EventType.REMOVE_TOTP).assertEvent();
+ }
+
+ @Test
+ public void changeProfileNoAccess() throws Exception {
+ profilePage.open();
+ loginPage.login("test-user-no-access@localhost", "password");
+
+ events.expectLogin().client("account").user(keycloakRule.getUser("test", "test-user-no-access@localhost").getId())
+ .detail(Details.USERNAME, "test-user-no-access@localhost")
+ .detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT).assertEvent();
+
+ Assert.assertTrue(errorPage.isCurrent());
+ Assert.assertEquals("No access", errorPage.getError());
+ }
+
+ @Test
+ public void viewLog() {
+ keycloakRule.update(new KeycloakSetup() {
+ @Override
+ public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+ appRealm.setEventsEnabled(true);
+ }
+ });
+
+ try {
+ List<Event> expectedEvents = new LinkedList<Event>();
+
+ loginPage.open();
+ loginPage.clickRegister();
+
+ registerPage.register("view", "log", "view-log@localhost", "view-log", "password", "password");
+
+ expectedEvents.add(events.poll());
+ expectedEvents.add(events.poll());
+
+ profilePage.open();
+ profilePage.updateProfile("view", "log2", "view-log@localhost");
+
+ expectedEvents.add(events.poll());
+
+ logPage.open();
+
+ Assert.assertTrue(logPage.isCurrent());
+
+ List<List<String>> actualEvents = logPage.getEvents();
+
+ Assert.assertEquals(expectedEvents.size(), actualEvents.size());
+
+ for (Event e : expectedEvents) {
+ boolean match = false;
+ for (List<String> a : logPage.getEvents()) {
+ if (e.getType().toString().replace('_', ' ').toLowerCase().equals(a.get(1)) &&
+ e.getIpAddress().equals(a.get(2)) &&
+ e.getClientId().equals(a.get(3))) {
+ match = true;
+ break;
+ }
+ }
+ if (!match) {
+ Assert.fail("Event not found " + e.getType());
+ }
+ }
+ } finally {
+ keycloakRule.update(new KeycloakSetup() {
+ @Override
+ public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+ appRealm.setEventsEnabled(false);
+ }
+ });
+ }
+ }
+
+ @Test
+ public void sessions() {
+ loginPage.open();
+ loginPage.clickRegister();
+
+ registerPage.register("view", "sessions", "view-sessions@localhost", "view-sessions", "password", "password");
+
+ Event registerEvent = events.expectRegister("view-sessions", "view-sessions@localhost").assertEvent();
+ String userId = registerEvent.getUserId();
+
+ events.expectLogin().user(userId).detail(Details.USERNAME, "view-sessions").assertEvent();
+
+ sessionsPage.open();
+
+ Assert.assertTrue(sessionsPage.isCurrent());
+
+ List<List<String>> sessions = sessionsPage.getSessions();
+ Assert.assertEquals(1, sessions.size());
+ Assert.assertEquals("127.0.0.1", sessions.get(0).get(0));
+
+ // Create second session
+ WebDriver driver2 = WebRule.createWebDriver();
+ try {
+ OAuthClient oauth2 = new OAuthClient(driver2);
+ oauth2.state("mystate");
+ oauth2.doLogin("view-sessions", "password");
+
+ Event login2Event = events.expectLogin().user(userId).detail(Details.USERNAME, "view-sessions").assertEvent();
+
+ sessionsPage.open();
+ sessions = sessionsPage.getSessions();
+ Assert.assertEquals(2, sessions.size());
+
+ sessionsPage.logoutAll();
+
+ events.expectLogout(registerEvent.getSessionId());
+ events.expectLogout(login2Event.getSessionId());
+ } finally {
+ driver2.close();
+ }
+ }
+
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java
index b7d39fc..6d3c32b 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java
@@ -30,11 +30,13 @@ import org.keycloak.Version;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.constants.AdapterConstants;
import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientSessionModel;
import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
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.OIDCLoginProtocolService;
import org.keycloak.protocol.oidc.TokenManager;
import org.keycloak.representations.AccessToken;
@@ -140,8 +142,10 @@ public class AdapterTestStrategy extends ExternalResource {
ApplicationModel adminConsole = adminRealm.getApplicationByName(Constants.ADMIN_CONSOLE_APPLICATION);
TokenManager tm = new TokenManager();
UserModel admin = session.users().getUserByUsername("admin", adminRealm);
+ ClientSessionModel clientSession = session.sessions().createClientSession(adminRealm, adminConsole);
+ clientSession.setNote(OIDCLoginProtocol.ISSUER, AUTH_SERVER_URL + "/realms/master");
UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, "admin", null, "form", false, null, null);
- AccessToken token = tm.createClientAccessToken(session, TokenManager.getAccess(null, adminConsole, admin), adminRealm, adminConsole, admin, userSession, null);
+ AccessToken token = tm.createClientAccessToken(session, TokenManager.getAccess(null, adminConsole, admin), adminRealm, adminConsole, admin, userSession, clientSession);
return tm.encodeToken(adminRealm, token);
} finally {
keycloakRule.stopSession(session, true);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/RelativeUriAdapterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/RelativeUriAdapterTest.java
index 56f8b8f..5c6ed7b 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/RelativeUriAdapterTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/RelativeUriAdapterTest.java
@@ -27,11 +27,13 @@ import org.junit.Rule;
import org.junit.Test;
import org.keycloak.OAuth2Constants;
import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientSessionModel;
import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
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.OIDCLoginProtocolService;
import org.keycloak.protocol.oidc.TokenManager;
import org.keycloak.representations.AccessToken;
@@ -86,8 +88,10 @@ public class RelativeUriAdapterTest {
ApplicationModel adminConsole = adminRealm.getApplicationByName(Constants.ADMIN_CONSOLE_APPLICATION);
TokenManager tm = new TokenManager();
UserModel admin = session.users().getUserByUsername("admin", adminRealm);
+ ClientSessionModel clientSession = session.sessions().createClientSession(realm, adminConsole);
+ clientSession.setNote(OIDCLoginProtocol.ISSUER, "http://localhost:8081/auth/realms/master");
UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, "user", null, "form", false, null, null);
- AccessToken token = tm.createClientAccessToken(session, tm.getAccess(null, adminConsole, admin), adminRealm, adminConsole, admin, userSession, null);
+ AccessToken token = tm.createClientAccessToken(session, tm.getAccess(null, adminConsole, admin), adminRealm, adminConsole, admin, userSession, clientSession);
adminToken = tm.encodeToken(adminRealm, token);
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java
index 873bbff..d72664a 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java
@@ -26,11 +26,13 @@ import org.junit.ClassRule;
import org.junit.Test;
import org.keycloak.Config;
import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientSessionModel;
import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
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.representations.AccessToken;
import org.keycloak.representations.idm.ApplicationRepresentation;
@@ -78,8 +80,10 @@ public class AdminAPITest {
ApplicationModel adminConsole = adminRealm.getApplicationByName(Constants.ADMIN_CONSOLE_APPLICATION);
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, 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);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ApplicationTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ApplicationTest.java
index 3c07797..e1902f9 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ApplicationTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ApplicationTest.java
@@ -3,9 +3,12 @@ package org.keycloak.testsuite.admin;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.admin.client.resource.ApplicationResource;
+import org.keycloak.admin.client.resource.ProtocolMappersResource;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.RealmModel;
+import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory;
import org.keycloak.representations.idm.ApplicationRepresentation;
+import org.keycloak.representations.idm.ProtocolMapperRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.UserSessionRepresentation;
@@ -17,6 +20,8 @@ import org.keycloak.testsuite.rule.WebRule;
import org.openqa.selenium.WebDriver;
import javax.ws.rs.NotFoundException;
+import javax.ws.rs.core.Response;
+
import java.util.LinkedList;
import java.util.List;
@@ -113,4 +118,63 @@ public class ApplicationTest extends AbstractClientTest {
assertNull(realm.applications().get("my-app").toRepresentation().getDefaultRoles());
}
+ @Test
+ public void testProtocolMappers() {
+ createApplication();
+ ProtocolMappersResource mappersResource = realm.applications().get("my-app").getProtocolMappers();
+
+ protocolMappersTest(mappersResource);
+ }
+
+
+ public static void protocolMappersTest(ProtocolMappersResource mappersResource) {
+ // assert default mappers found
+ List<ProtocolMapperRepresentation> protocolMappers = mappersResource.getMappers();
+
+ String emailMapperId = null;
+ String usernameMapperId = null;
+ String fooMapperId = null;
+ for (ProtocolMapperRepresentation mapper : protocolMappers) {
+ if (mapper.getName().equals(OIDCLoginProtocolFactory.EMAIL)) {
+ emailMapperId = mapper.getId();
+ } else if (mapper.getName().equals(OIDCLoginProtocolFactory.USERNAME)) {
+ usernameMapperId = mapper.getId();
+ } else if (mapper.getName().equals("foo")) {
+ fooMapperId = mapper.getId();
+ }
+ }
+
+ assertNotNull(emailMapperId);
+ assertNotNull(usernameMapperId);
+ assertNull(fooMapperId);
+
+ // Create foo mapper
+ ProtocolMapperRepresentation fooMapper = new ProtocolMapperRepresentation();
+ fooMapper.setName("foo");
+ fooMapper.setProtocol("fooProtocol");
+ fooMapper.setProtocolMapper("fooMapper");
+ fooMapper.setConsentRequired(true);
+ Response response = mappersResource.createMapper(fooMapper);
+ String location = response.getLocation().toString();
+ fooMapperId = location.substring(location.lastIndexOf("/") + 1);
+ response.close();
+
+ fooMapper = mappersResource.getMapperById(fooMapperId);
+ assertEquals(fooMapper.getName(), "foo");
+
+ // Update foo mapper
+ fooMapper.setProtocolMapper("foo-mapper-updated");
+ mappersResource.update(fooMapperId, fooMapper);
+
+ fooMapper = mappersResource.getMapperById(fooMapperId);
+ assertEquals(fooMapper.getProtocolMapper(), "foo-mapper-updated");
+
+ // Remove foo mapper
+ mappersResource.delete(fooMapperId);
+ try {
+ mappersResource.getMapperById(fooMapperId);
+ fail("Not expected to find deleted mapper");
+ } catch (NotFoundException nfe) {
+ }
+ }
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/OAuthClientTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/OAuthClientTest.java
index 44cf762..f064136 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/OAuthClientTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/OAuthClientTest.java
@@ -1,6 +1,7 @@
package org.keycloak.testsuite.admin;
import org.junit.Test;
+import org.keycloak.admin.client.resource.ProtocolMappersResource;
import org.keycloak.representations.idm.OAuthClientRepresentation;
import static org.junit.Assert.assertEquals;
@@ -34,6 +35,14 @@ public class OAuthClientTest extends AbstractClientTest {
}
@Test
+ public void testProtocolMappers() {
+ createOAuthClient();
+ ProtocolMappersResource mappersResource = realm.oAuthClients().get("my-client").getProtocolMappers();
+
+ ApplicationTest.protocolMappersTest(mappersResource);
+ }
+
+ @Test
public void getOAuthClientRepresentation() {
createOAuthClient();
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractIdentityProviderTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractIdentityProviderTest.java
index e6dbfcd..3fa93f1 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractIdentityProviderTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractIdentityProviderTest.java
@@ -153,7 +153,7 @@ public abstract class AbstractIdentityProviderTest {
UserModel federatedUser = assertSuccessfulAuthentication(identityProviderModel, "test-user-noemail", null);
- federatedUser.getRequiredActions().contains(RequiredAction.VERIFY_EMAIL);
+ assertTrue(federatedUser.getRequiredActions().contains(RequiredAction.VERIFY_EMAIL));
} finally {
getRealm().setVerifyEmail(false);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/IdentityProviderHintTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/IdentityProviderHintTest.java
index 20be993..9681873 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/IdentityProviderHintTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/IdentityProviderHintTest.java
@@ -38,6 +38,11 @@ public class IdentityProviderHintTest {
protected void configure(KeycloakSession session, RealmManager manager, RealmModel adminRealm) {
server.importRealm(getClass().getResourceAsStream("/broker-test/test-broker-realm-with-kc-oidc.json"));
}
+
+ @Override
+ protected String[] getTestRealms() {
+ return new String[] { "realm-with-oidc-identity-provider" };
+ }
};
@Rule
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/SAMLKeyCloakServerBrokerBasicTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/SAMLKeyCloakServerBrokerBasicTest.java
index 4b235eb..ffddbd2 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/SAMLKeyCloakServerBrokerBasicTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/SAMLKeyCloakServerBrokerBasicTest.java
@@ -19,6 +19,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
@@ -55,9 +56,12 @@ public class SAMLKeyCloakServerBrokerBasicTest extends AbstractIdentityProviderT
if (identityProviderModel.isUpdateProfileFirstLogin()) {
super.doAssertFederatedUser(federatedUser, identityProviderModel, expectedEmail);
} else {
- if (expectedEmail == null)
- expectedEmail = "";
- assertEquals(expectedEmail, federatedUser.getEmail());
+ if (expectedEmail == null) {
+ // Need to handle differences for various databases (like Oracle)
+ assertTrue(federatedUser.getEmail() == null || federatedUser.getEmail().equals(""));
+ } else {
+ assertEquals(expectedEmail, federatedUser.getEmail());
+ }
assertNull(federatedUser.getFirstName());
assertNull(federatedUser.getLastName());
}
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 5c7ac76..bef306c 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
@@ -18,6 +18,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
@@ -54,9 +55,12 @@ public class SAMLKeyCloakServerBrokerWithSignatureTest extends AbstractIdentityP
if (identityProviderModel.isUpdateProfileFirstLogin()) {
super.doAssertFederatedUser(federatedUser, identityProviderModel, expectedEmail);
} else {
- if (expectedEmail == null)
- expectedEmail = "";
- assertEquals(expectedEmail, federatedUser.getEmail());
+ if (expectedEmail == null) {
+ // Need to handle differences for various databases (like Oracle)
+ assertTrue(federatedUser.getEmail() == null || federatedUser.getEmail().equals(""));
+ } else {
+ assertEquals(expectedEmail, federatedUser.getEmail());
+ }
assertNull(federatedUser.getFirstName());
assertNull(federatedUser.getLastName());
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ApplicationModelTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ApplicationModelTest.java
index bb8c651..e55a325 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ApplicationModelTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ApplicationModelTest.java
@@ -65,7 +65,7 @@ public class ApplicationModelTest extends AbstractModelTest {
representation.setId(null);
RealmModel realm = realmManager.createRealm("copy");
- ApplicationModel copy = RepresentationToModel.createApplication(realm, representation, true);
+ ApplicationModel copy = RepresentationToModel.createApplication(session, realm, representation, true);
assertEquals(application, copy);
}
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 9319661..80d0310 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java
@@ -225,7 +225,7 @@ public class OAuthClient {
public AccessToken verifyToken(String token) {
try {
- return RSATokenVerifier.verifyToken(token, realmPublicKey, realm);
+ return RSATokenVerifier.verifyToken(token, realmPublicKey, baseUrl + "/realms/" + realm);
} catch (VerificationException e) {
throw new RuntimeException("Failed to verify token", e);
}
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 91970e6..a8391ae 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,474 +1,478 @@
-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.ApplicationModel;
-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.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.picketlink.common.constants.JBossSAMLURIConstants;
-import org.picketlink.identity.federation.api.saml.v2.response.SAML2Response;
-import org.picketlink.identity.federation.core.saml.v2.constants.X500SAMLProfileConstants;
-import org.picketlink.identity.federation.saml.v2.assertion.AssertionType;
-import org.picketlink.identity.federation.saml.v2.assertion.AttributeStatementType;
-import org.picketlink.identity.federation.saml.v2.assertion.AttributeType;
-import org.picketlink.identity.federation.saml.v2.protocol.ResponseType;
-import org.picketlink.identity.federation.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;
-
- //@Test
- public void runit() throws Exception {
- Thread.sleep(10000000);
- }
-
- 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) {
- ApplicationModel app = appRealm.getApplicationByName("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());
- ApplicationModel adminConsole = adminRealm.getApplicationByName(Constants.ADMIN_CONSOLE_APPLICATION);
- TokenManager tm = new TokenManager();
- UserModel admin = session.users().getUserByUsername("admin", adminRealm);
- 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, null);
- 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/application-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.ApplicationModel;
+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.picketlink.common.constants.JBossSAMLURIConstants;
+import org.picketlink.identity.federation.api.saml.v2.response.SAML2Response;
+import org.picketlink.identity.federation.core.saml.v2.constants.X500SAMLProfileConstants;
+import org.picketlink.identity.federation.saml.v2.assertion.AssertionType;
+import org.picketlink.identity.federation.saml.v2.assertion.AttributeStatementType;
+import org.picketlink.identity.federation.saml.v2.assertion.AttributeType;
+import org.picketlink.identity.federation.saml.v2.protocol.ResponseType;
+import org.picketlink.identity.federation.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;
+
+ //@Test
+ public void runit() throws Exception {
+ Thread.sleep(10000000);
+ }
+
+ 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) {
+ ApplicationModel app = appRealm.getApplicationByName("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());
+ ApplicationModel adminConsole = adminRealm.getApplicationByName(Constants.ADMIN_CONSOLE_APPLICATION);
+ 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/application-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/adapter-test/customer-db-keycloak.json b/testsuite/integration/src/test/resources/adapter-test/customer-db-keycloak.json
index 285b047..38d1179 100755
--- a/testsuite/integration/src/test/resources/adapter-test/customer-db-keycloak.json
+++ b/testsuite/integration/src/test/resources/adapter-test/customer-db-keycloak.json
@@ -2,6 +2,7 @@
"realm" : "demo",
"resource" : "customer-db",
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+ "auth-server-url": "http://localhost:8081/auth",
"ssl-required" : "external",
"bearer-only" : true,
"enable-cors" : true
diff --git a/testsuite/integration/src/test/resources/broker-test/test-realm-with-broker.json b/testsuite/integration/src/test/resources/broker-test/test-realm-with-broker.json
index 7174420..b419196 100755
--- a/testsuite/integration/src/test/resources/broker-test/test-realm-with-broker.json
+++ b/testsuite/integration/src/test/resources/broker-test/test-realm-with-broker.json
@@ -165,18 +165,6 @@
"userInfoUrl": "http://localhost:8082/auth/realms/realm-with-oidc-identity-provider/protocol/openid-connect/userinfo",
"defaultScope": "email profile"
}
- },
- {
- "alias" : "model-kerberos",
- "providerId" : "kerberos",
- "enabled": true,
- "updateProfileFirstLogin" : "true",
- "authenticateByDefault" : "false",
- "config": {
- "serverPrincipal": "HTTP/server.domain.org@DOMAIN.ORG",
- "keyTab": "/etc/http.keytab",
- "debug": "true"
- }
}
],
"users": [
@@ -242,4 +230,4 @@
}
]
}
-}
+}
diff --git a/testsuite/jetty/jetty81/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json b/testsuite/jetty/jetty81/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
index 285b047..38d1179 100755
--- a/testsuite/jetty/jetty81/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
+++ b/testsuite/jetty/jetty81/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
@@ -2,6 +2,7 @@
"realm" : "demo",
"resource" : "customer-db",
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+ "auth-server-url": "http://localhost:8081/auth",
"ssl-required" : "external",
"bearer-only" : true,
"enable-cors" : true
diff --git a/testsuite/jetty/jetty91/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json b/testsuite/jetty/jetty91/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
index 285b047..38d1179 100755
--- a/testsuite/jetty/jetty91/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
+++ b/testsuite/jetty/jetty91/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
@@ -2,6 +2,7 @@
"realm" : "demo",
"resource" : "customer-db",
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+ "auth-server-url": "http://localhost:8081/auth",
"ssl-required" : "external",
"bearer-only" : true,
"enable-cors" : true
diff --git a/testsuite/jetty/jetty92/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json b/testsuite/jetty/jetty92/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
index 285b047..38d1179 100755
--- a/testsuite/jetty/jetty92/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
+++ b/testsuite/jetty/jetty92/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
@@ -2,6 +2,7 @@
"realm" : "demo",
"resource" : "customer-db",
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+ "auth-server-url": "http://localhost:8081/auth",
"ssl-required" : "external",
"bearer-only" : true,
"enable-cors" : true
diff --git a/testsuite/performance-web/src/main/java/org/keycloak/testsuite/performance/web/OAuthClient.java b/testsuite/performance-web/src/main/java/org/keycloak/testsuite/performance/web/OAuthClient.java
index d5d2379..a57ee22 100755
--- a/testsuite/performance-web/src/main/java/org/keycloak/testsuite/performance/web/OAuthClient.java
+++ b/testsuite/performance-web/src/main/java/org/keycloak/testsuite/performance/web/OAuthClient.java
@@ -166,7 +166,7 @@ public class OAuthClient {
public AccessToken verifyToken(String token) {
try {
- return RSATokenVerifier.verifyToken(token, realmPublicKey, realm);
+ return RSATokenVerifier.verifyToken(token, realmPublicKey, baseUrl + "/" + realm);
} catch (VerificationException e) {
throw new RuntimeException("Failed to verify token", e);
}
diff --git a/testsuite/tomcat6/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json b/testsuite/tomcat6/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
index 285b047..38d1179 100755
--- a/testsuite/tomcat6/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
+++ b/testsuite/tomcat6/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
@@ -2,6 +2,7 @@
"realm" : "demo",
"resource" : "customer-db",
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+ "auth-server-url": "http://localhost:8081/auth",
"ssl-required" : "external",
"bearer-only" : true,
"enable-cors" : true
diff --git a/testsuite/tomcat7/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json b/testsuite/tomcat7/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
index 285b047..38d1179 100755
--- a/testsuite/tomcat7/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
+++ b/testsuite/tomcat7/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
@@ -2,6 +2,7 @@
"realm" : "demo",
"resource" : "customer-db",
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+ "auth-server-url": "http://localhost:8081/auth",
"ssl-required" : "external",
"bearer-only" : true,
"enable-cors" : true
diff --git a/testsuite/tomcat8/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json b/testsuite/tomcat8/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
index 285b047..912fef2 100755
--- a/testsuite/tomcat8/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
+++ b/testsuite/tomcat8/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json
@@ -2,8 +2,8 @@
"realm" : "demo",
"resource" : "customer-db",
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+ "auth-server-url": "http://localhost:8081/auth",
"ssl-required" : "external",
"bearer-only" : true,
"enable-cors" : true
-
-}
+}
\ No newline at end of file