KEYCLOAK-4271 Migration test for offline tokens

This commit is contained in:
mposolda 2017-01-26 17:19:03 +01:00
parent a8e2c8ef31
commit 42ad8aec64
7 changed files with 105 additions and 216 deletions

View file

@ -164,13 +164,20 @@ public class AuthServerTestEnricher {
return authServerInfo; return authServerInfo;
} }
public void startMigratedContainer(@Observes(precedence = 2) StartSuiteContainers event) { public void startMigratedContainer(@Observes(precedence = 3) StartSuiteContainers event) {
if (suiteContext.isAuthServerMigrationEnabled()) { if (suiteContext.isAuthServerMigrationEnabled()) {
log.info("\n\n### Starting keycloak " + System.getProperty("migrated.auth.server.version", "- previous") + " ###\n\n"); log.info("\n\n### Starting keycloak " + System.getProperty("migrated.auth.server.version", "- previous") + " ###\n\n");
startContainerEvent.fire(new StartContainer(suiteContext.getMigratedAuthServerInfo().getArquillianContainer())); startContainerEvent.fire(new StartContainer(suiteContext.getMigratedAuthServerInfo().getArquillianContainer()));
} }
} }
public void runPreMigrationTask(@Observes(precedence = 2) StartSuiteContainers event) {
if (suiteContext.isAuthServerMigrationEnabled()) {
log.info("\n\n### Run preMigration task on keycloak " + System.getProperty("migrated.auth.server.version", "- previous") + " ###\n\n");
suiteContext.getMigrationContext().runPreMigrationTask();
}
}
public void stopMigratedContainer(@Observes(precedence = 1) StartSuiteContainers event) { public void stopMigratedContainer(@Observes(precedence = 1) StartSuiteContainers event) {
if (suiteContext.isAuthServerMigrationEnabled()) { if (suiteContext.isAuthServerMigrationEnabled()) {
log.info("## STOP old container: " + suiteContext.getMigratedAuthServerInfo().getQualifier()); log.info("## STOP old container: " + suiteContext.getMigratedAuthServerInfo().getQualifier());

View file

@ -22,6 +22,8 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.keycloak.testsuite.arquillian.migration.MigrationContext;
import static org.keycloak.testsuite.util.MailServerConfiguration.FROM; import static org.keycloak.testsuite.util.MailServerConfiguration.FROM;
import static org.keycloak.testsuite.util.MailServerConfiguration.HOST; import static org.keycloak.testsuite.util.MailServerConfiguration.HOST;
import static org.keycloak.testsuite.util.MailServerConfiguration.PORT; import static org.keycloak.testsuite.util.MailServerConfiguration.PORT;
@ -38,6 +40,7 @@ public final class SuiteContext {
private final List<ContainerInfo> authServerBackendsInfo = new ArrayList<>(); private final List<ContainerInfo> authServerBackendsInfo = new ArrayList<>();
private ContainerInfo migratedAuthServerInfo; private ContainerInfo migratedAuthServerInfo;
private final MigrationContext migrationContext = new MigrationContext();
private boolean adminPasswordUpdated; private boolean adminPasswordUpdated;
private final Map<String, String> smtpServer = new HashMap<>(); private final Map<String, String> smtpServer = new HashMap<>();
@ -78,6 +81,10 @@ public final class SuiteContext {
return migratedAuthServerInfo; return migratedAuthServerInfo;
} }
public MigrationContext getMigrationContext() {
return migrationContext;
}
public void setMigratedAuthServerInfo(ContainerInfo migratedAuthServerInfo) { public void setMigratedAuthServerInfo(ContainerInfo migratedAuthServerInfo) {
this.migratedAuthServerInfo = migratedAuthServerInfo; this.migratedAuthServerInfo = migratedAuthServerInfo;
} }

View file

@ -0,0 +1,58 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.arquillian.migration;
import org.jboss.logging.Logger;
import org.keycloak.OAuth2Constants;
import org.keycloak.testsuite.util.OAuthClient;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class MigrationContext {
public static final Logger logger = Logger.getLogger(MigrationContext.class);
private String offlineToken;
public String getOfflineToken() {
return offlineToken;
}
// Do some actions on the old container
public void runPreMigrationTask() {
requestOfflineToken();
}
private void requestOfflineToken() {
logger.info("Requesting offline token on the old container");
try {
OAuthClient oauth = new OAuthClient();
oauth.init(null, null);
oauth.scope(OAuth2Constants.OFFLINE_ACCESS);
oauth.realm("Migration");
oauth.clientId("migration-test-client");
OAuthClient.AccessTokenResponse tokenResponse = oauth.doGrantAccessTokenRequest("b2c07929-69e3-44c6-8d7f-76939000b3e4", "migration-test-user", "admin");
offlineToken = tokenResponse.getRefreshToken();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

View file

@ -35,6 +35,7 @@ import org.keycloak.models.Constants;
import org.keycloak.models.LDAPConstants; import org.keycloak.models.LDAPConstants;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.models.utils.DefaultAuthenticationFlows; import org.keycloak.models.utils.DefaultAuthenticationFlows;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.idm.AuthenticationExecutionExportRepresentation; import org.keycloak.representations.idm.AuthenticationExecutionExportRepresentation;
import org.keycloak.representations.idm.AuthenticationFlowRepresentation; import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.ClientRepresentation;
@ -47,7 +48,9 @@ import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.authorization.PolicyRepresentation; import org.keycloak.representations.idm.authorization.PolicyRepresentation;
import org.keycloak.storage.UserStorageProvider; import org.keycloak.storage.UserStorageProvider;
import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.AbstractKeycloakTest;
import org.keycloak.testsuite.Assert;
import org.keycloak.testsuite.arquillian.migration.Migration; import org.keycloak.testsuite.arquillian.migration.Migration;
import org.keycloak.testsuite.util.OAuthClient;
import static org.keycloak.testsuite.Assert.assertEquals; import static org.keycloak.testsuite.Assert.assertEquals;
import static org.keycloak.testsuite.Assert.assertFalse; import static org.keycloak.testsuite.Assert.assertFalse;
@ -104,6 +107,7 @@ public class MigrationTest extends AbstractKeycloakTest {
testMigrationTo2_2_0(); testMigrationTo2_2_0();
testMigrationTo2_3_0(); testMigrationTo2_3_0();
testMigrationTo2_5_0(); testMigrationTo2_5_0();
testMigrationTo2_5_1();
} }
@Test @Test
@ -168,6 +172,10 @@ public class MigrationTest extends AbstractKeycloakTest {
//https://github.com/keycloak/keycloak/pull/3630 //https://github.com/keycloak/keycloak/pull/3630
testDuplicateEmailSupport(masterRealm, migrationRealm); testDuplicateEmailSupport(masterRealm, migrationRealm);
} }
private void testMigrationTo2_5_1() {
testOfflineTokenLogin();
}
private void testExtractRealmKeys(RealmResource masterRealm, RealmResource migrationRealm) { private void testExtractRealmKeys(RealmResource masterRealm, RealmResource migrationRealm) {
log.info("testing extract realm keys"); log.info("testing extract realm keys");
@ -337,4 +345,16 @@ public class MigrationTest extends AbstractKeycloakTest {
assertFalse("DuplicateEmailsAllowed should be disabled.", rep.isDuplicateEmailsAllowed()); assertFalse("DuplicateEmailsAllowed should be disabled.", rep.isDuplicateEmailsAllowed());
} }
} }
private void testOfflineTokenLogin() {
log.info("test login with old offline token");
String oldOfflineToken = suiteContext.getMigrationContext().getOfflineToken();
Assert.assertNotNull(oldOfflineToken);
oauth.realm(MIGRATION);
oauth.clientId("migration-test-client");
OAuthClient.AccessTokenResponse response = oauth.doRefreshTokenRequest(oldOfflineToken, "b2c07929-69e3-44c6-8d7f-76939000b3e4");
AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
assertEquals("migration-test-user", accessToken.getPreferredUsername());
}
} }

View file

@ -1,212 +0,0 @@
{
"id" : "14e6923c-f5fb-44aa-8982-35d4976c56c5",
"realm" : "foo11",
"notBefore" : 0,
"accessTokenLifespan" : 300,
"ssoSessionIdleTimeout" : 1800,
"ssoSessionMaxLifespan" : 36000,
"accessCodeLifespan" : 60,
"accessCodeLifespanUserAction" : 300,
"enabled" : true,
"sslRequired" : "external",
"passwordCredentialGrantAllowed" : false,
"registrationAllowed" : false,
"rememberMe" : false,
"verifyEmail" : false,
"resetPasswordAllowed" : false,
"social" : false,
"updateProfileOnInitialSocialLogin" : false,
"bruteForceProtected" : false,
"maxFailureWaitSeconds" : 900,
"minimumQuickLoginWaitSeconds" : 60,
"waitIncrementSeconds" : 60,
"quickLoginCheckMilliSeconds" : 1000,
"maxDeltaTimeSeconds" : 43200,
"failureFactor" : 30,
"privateKey" : "MIICXQIBAAKBgQC05JPgp3F/lxuKMmf6TNs5YtumvoFL88eQ9UPhYn768CHc/PDNRBu3VN8GxwgbkUEX/I5s+nTWo8bKJAxdDyGRlAYItanJxH5iCe152cuEAY0kkHunDvsgAKx7snUztYJ7kC1b+B8I+9a6D0yXwwAZMHlOvF+QXKIiDzB8Cvww+QIDAQABAoGAIW/G7dXFowH5czgSBDBErXzagR3hpHpxPxg27ehY9GWCvOh8UlTukpq7hvMvSnk1AQwL/5TkF/C6BA9ZwbHUUFZduRFuut/Dsm8FtT5MiwdjmBBbcoQNZ6MlC4meHZBR/cRvu5ABQa2ChR6csMDISSHSh2lliPticfvZWZyKvAECQQDylYgBDeL6/0q+GCS1lO2FIncg/sRVqINZI7Ald+C3+VHtWlvPqbMvUDBKFBQMV4qH+JOUkvVLgXITbZHGAaK5AkEAvuWhpdzbR9CdxMsOeVb6Jg5MJGSbZBNY+e/diqwbnSNtt1VYqrPEeaOwFLm7g7/ODbwsDBh2sw68898zr7DgQQJATaRuk2fObmenlJBFr5irLSGK35SrYn89CxrRFiz4T+oMvttc52p5X3ta+VrTz991B3AYTEV9HV2hFXbMYYPEgQJBAKtmy4l9kHYe3knAeLKCYgChfcR/gPaOWKmxsZ29gt3I3c5rFz3OQ29khclWKwPUyFKUzofdv1ZuuUHO+z2Y9wECQQC/AJmkiMWGp9Ol3gbM7KhLS8CFLxFlPdBav5EqOxPmFUQQvSStUq3zoLpuYJKlXC5D5tbd7pNf5b1XycEtbRXH",
"publicKey" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC05JPgp3F/lxuKMmf6TNs5YtumvoFL88eQ9UPhYn768CHc/PDNRBu3VN8GxwgbkUEX/I5s+nTWo8bKJAxdDyGRlAYItanJxH5iCe152cuEAY0kkHunDvsgAKx7snUztYJ7kC1b+B8I+9a6D0yXwwAZMHlOvF+QXKIiDzB8Cvww+QIDAQAB",
"certificate" : "MIIBkzCB/QIGAVPnGn2KMA0GCSqGSIb3DQEBCwUAMBAxDjAMBgNVBAMTBWZvbzExMB4XDTE2MDQwNTE1NDQ0NloXDTI2MDQwNTE1NDYyNlowEDEOMAwGA1UEAxMFZm9vMTEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALTkk+CncX+XG4oyZ/pM2zli26a+gUvzx5D1Q+FifvrwIdz88M1EG7dU3wbHCBuRQRf8jmz6dNajxsokDF0PIZGUBgi1qcnEfmIJ7XnZy4QBjSSQe6cO+yAArHuydTO1gnuQLVv4Hwj71roPTJfDABkweU68X5BcoiIPMHwK/DD5AgMBAAEwDQYJKoZIhvcNAQELBQADgYEAsB4JWLBGFIaPAJAnZ8BMGuVoQhNtRxUD4htX/enKpuiQM3u0Nw4sFotJG8xvnxucJheCB8DpvIcAVmaARqLJ0bvfJ4wbP70cWd3iCvxoiiXtjpSQy/0rOTeGiYcnnwZC+ffpOzTGe4OoPdYymjrmubeIyRrF+ijmH2n2Rn4ELXw=",
"codeSecret" : "0af1be0b-2fdb-4037-9e6a-1e3370bf9f15",
"roles" : {
"application" : {
"realm-management" : [ {
"id" : "eaaf02b4-a38e-4fca-8689-a4ace644c7d9",
"name" : "manage-applications",
"composite" : false
}, {
"id" : "ce48589c-1459-4b75-ac99-45fd9255e562",
"name" : "manage-events",
"composite" : false
}, {
"id" : "ac30d420-da49-4ac6-83f8-2a6be5b5435d",
"name" : "view-users",
"composite" : false
}, {
"id" : "6f465ced-4722-4059-8300-104a68d5fd98",
"name" : "view-realm",
"composite" : false
}, {
"id" : "0f3060f4-2097-4e8b-8852-b8b27be11b6b",
"name" : "view-events",
"composite" : false
}, {
"id" : "1ceb312c-a5ae-4199-b567-81bef7d9103f",
"name" : "manage-realm",
"composite" : false
}, {
"id" : "d36d799b-0fa1-48eb-8b45-3bfc1eab817e",
"name" : "view-applications",
"composite" : false
}, {
"id" : "7d04fc11-2d52-4aca-9f79-e3d1782e4eef",
"name" : "manage-clients",
"composite" : false
}, {
"id" : "1c233305-6941-407f-8058-dfdf40f7d87f",
"name" : "realm-admin",
"composite" : true,
"composites" : {
"application" : {
"realm-management" : [ "manage-applications", "manage-events", "view-users", "view-realm", "view-events", "manage-realm", "view-applications", "manage-clients", "view-clients", "manage-users" ]
}
}
}, {
"id" : "29fe8dc9-ec74-42bf-b11a-3592aa205612",
"name" : "view-clients",
"composite" : false
}, {
"id" : "ac0059d0-bbe5-4247-ab82-5d408a1e9e19",
"name" : "manage-users",
"composite" : false
} ],
"security-admin-console" : [ ],
"account" : [ {
"id" : "44d8d987-62e4-4235-afd8-c0f7e7c5c280",
"name" : "view-profile",
"composite" : false
}, {
"id" : "03c1c19b-1732-488d-afc6-b5962e1d5fcd",
"name" : "manage-account",
"composite" : false
} ]
}
},
"requiredCredentials" : [ "password" ],
"users" : [ {
"id" : "2de2f04e-ff3b-4c22-b98d-6e3689bb2108",
"username" : "john11",
"enabled" : true,
"totp" : false,
"emailVerified" : false,
"email" : "john11@email.cz",
"credentials" : [ {
"type" : "password",
"hashedSaltedValue" : "2iUgsRh4EU4OV1nucya5UGCtQ34g/dpF8S1fKR77SsC0MrGpb1IKW7VOxGrooaQdxyzwFl48wXy68QFlkk6BcQ==",
"salt" : "rkzFU40mN8yVa7agq3SXMA==",
"hashIterations" : 1,
"temporary" : false
} ],
"requiredActions" : [ ],
"applicationRoles" : {
"realm-management" : [ "manage-applications" ],
"account" : [ "view-profile", "manage-account" ]
}
} ],
"applicationScopeMappings" : {
"realm-management" : [ {
"client" : "security-admin-console",
"roles" : [ "realm-admin" ]
} ]
},
"applications" : [ {
"id" : "c7a9cf59-feeb-44a4-a467-e008e157efa2",
"name" : "realm-management",
"surrogateAuthRequired" : false,
"enabled" : true,
"secret" : "1bceb96f-9abe-4a8a-9d76-5989e87a981e",
"redirectUris" : [ ],
"webOrigins" : [ ],
"claims" : {
"name" : true,
"username" : true,
"profile" : true,
"picture" : true,
"website" : true,
"email" : true,
"gender" : true,
"locale" : true,
"address" : true,
"phone" : true
},
"notBefore" : 0,
"bearerOnly" : true,
"publicClient" : false,
"attributes" : { },
"fullScopeAllowed" : false,
"nodeReRegistrationTimeout" : 0
}, {
"id" : "0715aa1a-0b7d-4594-a315-741205441910",
"name" : "account",
"baseUrl" : "/auth/realms/foo11/account",
"surrogateAuthRequired" : false,
"enabled" : true,
"secret" : "c7378e28-201c-4fd0-8482-ad5ea78adc51",
"defaultRoles" : [ "view-profile", "manage-account" ],
"redirectUris" : [ "/auth/realms/foo11/account/*" ],
"webOrigins" : [ ],
"claims" : {
"name" : true,
"username" : true,
"profile" : true,
"picture" : true,
"website" : true,
"email" : true,
"gender" : true,
"locale" : true,
"address" : true,
"phone" : true
},
"notBefore" : 0,
"bearerOnly" : false,
"publicClient" : false,
"attributes" : { },
"fullScopeAllowed" : false,
"nodeReRegistrationTimeout" : 0
}, {
"id" : "a9ca4217-74a8-4658-92c8-c2f9ed48a474",
"name" : "security-admin-console",
"baseUrl" : "/auth/admin/foo11/console/index.html",
"surrogateAuthRequired" : false,
"enabled" : true,
"secret" : "a5fd322f-6d2b-463c-b2af-bbc56f772462",
"redirectUris" : [ "/auth/admin/foo11/console/*" ],
"webOrigins" : [ ],
"claims" : {
"name" : true,
"username" : true,
"profile" : true,
"picture" : true,
"website" : true,
"email" : true,
"gender" : true,
"locale" : true,
"address" : true,
"phone" : true
},
"notBefore" : 0,
"bearerOnly" : false,
"publicClient" : true,
"attributes" : { },
"fullScopeAllowed" : false,
"nodeReRegistrationTimeout" : 0
} ],
"oauthClients" : [ ],
"browserSecurityHeaders" : {
"xFrameOptions" : "SAMEORIGIN",
"contentSecurityPolicy" : "frame-src 'self'"
},
"socialProviders" : { },
"smtpServer" : { },
"eventsEnabled" : false,
"eventsListeners" : [ ]
}

View file

@ -23,7 +23,7 @@ log4j.appender.keycloak.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%c] %m%n
log4j.appender.testsuite=org.apache.log4j.ConsoleAppender log4j.appender.testsuite=org.apache.log4j.ConsoleAppender
log4j.appender.testsuite.layout=org.apache.log4j.PatternLayout log4j.appender.testsuite.layout=org.apache.log4j.PatternLayout
log4j.appender.testsuite.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p %m%n log4j.appender.testsuite.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%C{1}] %m%n
log4j.logger.org.keycloak=off, keycloak log4j.logger.org.keycloak=off, keycloak

View file

@ -1743,7 +1743,16 @@
"enabled" : true, "enabled" : true,
"totp" : false, "totp" : false,
"emailVerified" : false, "emailVerified" : false,
"credentials" : [ ], "credentials" : [ {
"type" : "password",
"hashedSaltedValue" : "Y71bKP3V5cvqiPGxPspDCQRraGbJD4IGxjYOez4QdubTYpoFjYb2wdC+pRoXskBvOaCYQcGzMa3SatDrFlBm9Q==",
"salt" : "o6D0KTKeFVejy00RhKZxvQ==",
"hashIterations" : 20000,
"counter" : 0,
"algorithm" : "pbkdf2",
"digits" : 0,
"createdDate" : 1476260086000
} ],
"requiredActions" : [ ], "requiredActions" : [ ],
"realmRoles" : [ "offline_access" ], "realmRoles" : [ "offline_access" ],
"clientRoles" : { "clientRoles" : {
@ -2091,7 +2100,7 @@
"implicitFlowEnabled" : false, "implicitFlowEnabled" : false,
"directAccessGrantsEnabled" : true, "directAccessGrantsEnabled" : true,
"serviceAccountsEnabled" : false, "serviceAccountsEnabled" : false,
"publicClient" : true, "publicClient" : false,
"frontchannelLogout" : false, "frontchannelLogout" : false,
"protocol" : "openid-connect", "protocol" : "openid-connect",
"attributes" : { }, "attributes" : { },