Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Bill Burke 2016-07-07 10:35:45 -04:00
commit 0040d3fc3b
127 changed files with 1936 additions and 649 deletions

View file

@ -25,7 +25,7 @@
var kc = this;
var adapter;
var refreshQueue = [];
var storage;
var callbackStorage;
var loginIframe = {
enable: true,
@ -36,7 +36,7 @@
kc.init = function (initOptions) {
kc.authenticated = false;
storage = new PersistentStorage();
callbackStorage = createCallbackStorage();
if (initOptions && initOptions.adapter === 'cordova') {
adapter = loadAdapter('cordova');
@ -201,7 +201,7 @@
redirectUri += (redirectUri.indexOf('?') == -1 ? '?' : '&') + 'prompt=' + options.prompt;
}
storage.setItem('oauthState', JSON.stringify({ state: state, nonce: nonce, redirectUri: encodeURIComponent(redirectUri) }));
callbackStorage.add({ state: state, nonce: nonce, redirectUri: encodeURIComponent(redirectUri) });
var action = 'auth';
if (options && options.action == 'register') {
@ -697,15 +697,11 @@
function parseCallback(url) {
var oauth = new CallbackParser(url, kc.responseMode).parseUri();
var oauthState = callbackStorage.get(oauth.state);
var oauthState = storage.getItem('oauthState');
var sessionState = oauthState && JSON.parse(oauthState);
if (sessionState && (oauth.code || oauth.error || oauth.access_token || oauth.id_token) && oauth.state && oauth.state == sessionState.state) {
storage.removeItem('oauthState');
oauth.redirectUri = sessionState.redirectUri;
oauth.storedNonce = sessionState.nonce;
if (oauthState && (oauth.code || oauth.error || oauth.access_token || oauth.id_token)) {
oauth.redirectUri = oauthState.redirectUri;
oauth.storedNonce = oauthState.nonce;
if (oauth.fragment) {
oauth.newUrl += '#' + oauth.fragment;
@ -792,8 +788,22 @@
if (event.origin !== loginIframe.iframeOrigin) {
return;
}
try {
var data = JSON.parse(event.data);
} catch (err) {
return;
}
if (!data.callbackId) {
return;
}
var promise = loginIframe.callbackMap[data.callbackId];
if (!promise) {
return;
}
delete loginIframe.callbackMap[data.callbackId];
if ((!kc.sessionId || kc.sessionId == data.session) && data.loggedIn) {
@ -982,60 +992,93 @@
throw 'invalid adapter type: ' + type;
}
var LocalStorage = function() {
if (!(this instanceof LocalStorage)) {
return new LocalStorage();
}
var PersistentStorage = function() {
if (!(this instanceof PersistentStorage)) {
return new PersistentStorage();
}
var ps = this;
var useCookieStorage = function () {
if (typeof localStorage === "undefined") {
return true;
}
localStorage.setItem('kc-test', 'test');
localStorage.removeItem('kc-test');
var cs = this;
function clearExpired() {
var time = new Date().getTime();
for (var i = 1; i <= localStorage.length; i++) {
var key = localStorage.key(i);
if (key && key.indexOf('kc-callback-') == 0) {
var value = localStorage.getItem(key);
if (value) {
try {
var key = '@@keycloak-session-storage/test';
localStorage.setItem(key, 'test');
var expires = JSON.parse(value).expires;
if (!expires || expires < time) {
localStorage.removeItem(key);
return false;
}
} catch (err) {
// Probably in Safari "private mode" where localStorage
// quota is 0, or quota exceeded. Switching to cookie
// storage.
return true;
}
}
ps.setItem = function(key, value) {
if (useCookieStorage()) {
setCookie(key, value, cookieExpiration(5));
} else {
localStorage.setItem(key, value);
}
}
ps.getItem = function(key) {
if (useCookieStorage()) {
return getCookie(key);
}
return localStorage.getItem(key);
}
ps.removeItem = function(key) {
if (typeof localStorage !== "undefined") {
try {
// Always try to delete from localStorage.
localStorage.removeItem(key);
} catch (err) { }
}
// Always remove the cookie.
}
}
}
}
cs.get = function(state) {
if (!state) {
return;
}
var key = 'kc-callback-' + state;
var value = localStorage.getItem(key);
if (value) {
localStorage.removeItem(key);
value = JSON.parse(value);
}
clearExpired();
return value;
};
cs.add = function(state) {
clearExpired();
var key = 'kc-callback-' + state.state;
state.expires = new Date().getTime() + (60 * 60 * 1000);
localStorage.setItem(key, JSON.stringify(state));
};
};
var CookieStorage = function() {
if (!(this instanceof CookieStorage)) {
return new CookieStorage();
}
var cs = this;
cs.get = function(state) {
if (!state) {
return;
}
var value = getCookie('kc-callback-' + state);
setCookie('kc-callback-' + state, '', cookieExpiration(-100));
if (value) {
return JSON.parse(value);
}
};
cs.add = function(state) {
setCookie('kc-callback-' + state.state, JSON.stringify(state), cookieExpiration(60));
};
cs.removeItem = function(key) {
setCookie(key, '', cookieExpiration(-100));
}
};
var cookieExpiration = function (minutes) {
var exp = new Date();
exp.setTime(exp.getTime() + (minutes*60*1000));
return exp;
}
};
var getCookie = function (key) {
var name = key + '=';
@ -1050,13 +1093,22 @@
}
}
return '';
}
};
var setCookie = function (key, value, expirationDate) {
var cookie = key + '=' + value + '; '
+ 'expires=' + expirationDate.toUTCString() + '; ';
document.cookie = cookie;
}
};
function createCallbackStorage() {
try {
return new LocalStorage();
} catch (err) {
}
return new CookieStorage();
}
var CallbackParser = function(uriToParse, responseMode) {

View file

@ -77,6 +77,13 @@
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<!-- Authorization -->
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-authz-client</artifactId>
</dependency>
<!--
<dependency>
<groupId>org.apache.tomcat</groupId>

View file

@ -21,6 +21,7 @@ import com.fasterxml.jackson.core.type.TypeReference;
import org.keycloak.common.util.Base64Url;
import org.keycloak.util.JsonSerialization;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.PublicKey;

View file

@ -33,6 +33,7 @@ import java.security.PrivateKey;
*/
public class JWSBuilder {
String type;
String kid;
String contentType;
byte[] contentBytes;
@ -41,6 +42,11 @@ public class JWSBuilder {
return this;
}
public JWSBuilder kid(String kid) {
this.kid = kid;
return this;
}
public JWSBuilder contentType(String type) {
this.contentType = type;
return this;
@ -66,6 +72,7 @@ public class JWSBuilder {
builder.append("\"alg\":\"").append(alg.toString()).append("\"");
if (type != null) builder.append(",\"typ\" : \"").append(type).append("\"");
if (kid != null) builder.append(",\"kid\" : \"").append(kid).append("\"");
if (contentType != null) builder.append(",\"cty\":\"").append(contentType).append("\"");
builder.append("}");
try {

View file

@ -90,9 +90,6 @@
<local-cache name="offlineSessions"/>
<local-cache name="loginFailures"/>
<local-cache name="work"/>
<local-cache name="realmVersions">
<transaction mode="BATCH" locking="PESSIMISTIC"/>
</local-cache>
</cache-container>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>

View file

@ -8,7 +8,5 @@ embed-server --server-config=standalone-ha.xml
/subsystem=infinispan/cache-container=keycloak/distributed-cache=offlineSessions:add(mode="SYNC",owners="1")
/subsystem=infinispan/cache-container=keycloak/distributed-cache=loginFailures:add(mode="SYNC",owners="1")
/subsystem=infinispan/cache-container=keycloak/replicated-cache=work:add(mode="SYNC")
/subsystem=infinispan/cache-container=keycloak/local-cache=realmVersions:add()
/subsystem=infinispan/cache-container=keycloak/local-cache=realmVersions/transaction=TRANSACTION:add(mode=BATCH,locking=PESSIMISTIC)
/extension=org.keycloak.keycloak-server-subsystem/:add(module=org.keycloak.keycloak-server-subsystem)
/subsystem=keycloak-server:add(web-context=auth)

View file

@ -1,139 +0,0 @@
## Test
* Make sure tests pass on Travis (https://travis-ci.org/keycloak/keycloak)
* Make sure tests pass on Jenkins (https://jenkins.mw.lab.eng.bos.redhat.com/hudson/view/Keycloak/job/keycloak_all/)
* Go through the (manual testing)[https://docs.google.com/spreadsheets/d/17C_WEHNE03r5DxN71OXGJaytjA6_WjZKCXRcsnmNQD4]
## Release
### Clone from GitHub
# git clone https://github.com/keycloak/keycloak.git
# cd keycloak
### Prepare the release
# mvn -Pjboss-release release:prepare
### Perform the release
# mvn -Pjboss-release release:perform
### Deploy to Nexus
Then login to Nexus and release the maven uploads in the staging area. Artifacts will eventually be synced to Maven Central, but this can take up to 24 hours.
### Upload
Upload all artifacts to downloads.jboss.org (see https://mojo.redhat.com/docs/DOC-81955 for more details):
# rsync -rv --protocol=28 distribution/downloads/target/$VERSION keycloak@filemgmt.jboss.org:/downloads_htdocs/keycloak
### Upload documentation
# git clone https://github.com/keycloak/keycloak.github.io.git
# cd keycloak.github.io
# rm -rf docs
# unzip ../distribution/downloads/target/$VERSION/keycloak-docs-$VERSION.zip
# mv keycloak-docs-$VERSION docs
# git commit -m "Updated docs to $VERSION"
# git tag $VERSION
# git push --tags
## After Release
### Update Bower
# git clone https://github.com/keycloak/keycloak-js-bower
# cd keycloak-js-bower
# unzip ../distribution/downloads/target/$VERSION/adapters/keycloak-js-adapter-dist-$VERSION.zip
# mv keycloak-js-adapter-dist-$VERSION/*.js dist/keycloak-js-bower
# rmdir keycloak-js-adapter-dist-$VERSION
Edit bower.json and set version (include -beta -rc, but not -final). Then commit create tag:
# git commit -m "Updated to $VERSION"
# git tag $VERSION
# git push --tags
### Update Website
* Edit [Docs page](https://www.jboss.org/author/keycloak/docs.html) and update version
* Edit [Downloads page](https://www.jboss.org/author/keycloak/downloads) edit directory listing component and update version in title and project root
### Announce release
Write a blog post on blog.keycloak.org, blurb about what's new and include links to website for download and jira for changes.
Copy blog post and send to keycloak-dev and keycloak-users mailing lists.
Post link to blog post on Twitter (with Keycloak user).
### Update OpenShift Cartridge
The OpenShift Cartridge has a base branch that is based on the WildFly cartridge and includes any changes related to Keycloak, but does not include Keycloak
itself. Any configuration changes or upgrading WildFly should be done in the base branch.
To include changes from the WildFly cartridge, for example when upgrading to a new WildFly version the base branch should be rebased on from the [wildfly-cartridge](https://github.com/openshift-cartridges/openshift-wildfly-cartridge):
# git clone https://github.com/keycloak/openshift-keycloak-cartridge.git
# cd openshift-keycloak-cartridge
# git remote add wildfly https://github.com/openshift-cartridges/openshift-wildfly-cartridge.git
# git fetch wildfly
# git checkout base
# git rebase wildfly
# git push orgin base:base
To upgrade Keycloak on the cartridge run:
# git clone https://github.com/openshift-cartridges/openshift-wildfly-cartridge.git
# cd openshift-keycloak-cartridge
To remove the previous release of Keycloak on master run:
# git reset --hard upstream/base
Once you've done that install the Keycloak overlay:
# cd versions/9
# unzip keycloak-overlay-$VERSION.zip
# git commit -m "Install Keycloak $VERSION" -a
# git tag $VERSION
# git push --tags master
### Update Docker image
# git clone https://github.com/jboss-dockerfiles/keycloak.git
# cd keycloak
Edit server/Dockerfile and update version in `ENV KEYCLOAK_VERSION ...` line.
Edit the following files:
* server-postgres/Dockerfile
* adapter-wildfly/Dockerfile
* server-ha-postgres/Dockerfile
* server/Dockerfile
* server-mongo/Dockerfile
* examples/Dockerfile
* server-mysql/Dockerfile
And update version in `FROM jboss/keycloak:...` line.
# git commit -m "Updated to $VERSION" -a
# git tag $VERSION
# git push --tags master
Go to Docker Hub. Update build settings for the following images and change `Name` and `Docker Tag Name` to the version you are releasing:
* [keycloak](https://hub.docker.com/r/jboss/keycloak/~/settings/automated-builds/)
* [adapter-wildfly](https://hub.docker.com/r/jboss/keycloak-adapter-wildfly/~/settings/automated-builds/)
* [examples](https://hub.docker.com/r/jboss/keycloak-examples/~/settings/automated-builds/)
* [postgres](https://hub.docker.com/r/jboss/keycloak-postgres/~/settings/automated-builds/)
* [mysql](https://hub.docker.com/r/jboss/keycloak-mysql/~/settings/automated-builds/)
* [mongo](https://hub.docker.com/r/jboss/keycloak-mongo/~/settings/automated-builds/)
* [ha-postgres](https://hub.docker.com/r/jboss/keycloak-ha-postgres/~/settings/automated-builds/)
Once you've updated all images. Schedule a build of the [keycloak image](https://hub.docker.com/r/jboss/keycloak/builds/). Once completed it will trigger
builds of all other images as they are linked.

View file

@ -21,6 +21,7 @@ import org.infinispan.configuration.cache.CacheMode;
import org.infinispan.configuration.cache.Configuration;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.configuration.global.GlobalConfigurationBuilder;
import org.infinispan.eviction.EvictionStrategy;
import org.infinispan.eviction.EvictionType;
import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.manager.EmbeddedCacheManager;
@ -97,6 +98,17 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
cacheManager = (EmbeddedCacheManager) new InitialContext().lookup(cacheContainerLookup);
containerManaged = true;
cacheManager.defineConfiguration(InfinispanConnectionProvider.REALM_REVISIONS_CACHE_NAME, getRevisionCacheConfig(true, InfinispanConnectionProvider.REALM_REVISIONS_CACHE_DEFAULT_MAX));
cacheManager.getCache(InfinispanConnectionProvider.REALM_CACHE_NAME, true);
long maxEntries = cacheManager.getCache(InfinispanConnectionProvider.USER_CACHE_NAME).getCacheConfiguration().eviction().maxEntries();
if (maxEntries <= 0) {
maxEntries = InfinispanConnectionProvider.USER_REVISIONS_CACHE_DEFAULT_MAX;
}
cacheManager.defineConfiguration(InfinispanConnectionProvider.USER_REVISIONS_CACHE_NAME, getRevisionCacheConfig(true, maxEntries));
cacheManager.getCache(InfinispanConnectionProvider.USER_REVISIONS_CACHE_NAME, true);
logger.debugv("Using container managed Infinispan cache container, lookup={1}", cacheContainerLookup);
} catch (Exception e) {
throw new RuntimeException("Failed to retrieve cache container", e);
@ -162,12 +174,32 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
.transaction().transactionMode(TransactionMode.TRANSACTIONAL);
counterConfigBuilder.transaction().transactionManagerLookup(new DummyTransactionManagerLookup());
counterConfigBuilder.transaction().lockingMode(LockingMode.PESSIMISTIC);
Configuration counterCacheConfiguration = counterConfigBuilder.build();
cacheManager.defineConfiguration(InfinispanConnectionProvider.VERSION_CACHE_NAME, counterCacheConfiguration);
cacheManager.defineConfiguration(InfinispanConnectionProvider.REALM_REVISIONS_CACHE_NAME, getRevisionCacheConfig(false, InfinispanConnectionProvider.REALM_REVISIONS_CACHE_DEFAULT_MAX));
cacheManager.getCache(InfinispanConnectionProvider.REALM_CACHE_NAME, true);
cacheManager.defineConfiguration(InfinispanConnectionProvider.AUTHORIZATION_CACHE_NAME,
new ConfigurationBuilder().eviction().type(EvictionType.COUNT).size(100).simpleCache(true).build());
long maxEntries = cacheManager.getCache(InfinispanConnectionProvider.USER_CACHE_NAME).getCacheConfiguration().eviction().maxEntries();
if (maxEntries <= 0) {
maxEntries = InfinispanConnectionProvider.USER_REVISIONS_CACHE_DEFAULT_MAX;
}
cacheManager.defineConfiguration(InfinispanConnectionProvider.USER_REVISIONS_CACHE_NAME, getRevisionCacheConfig(false, maxEntries));
cacheManager.getCache(InfinispanConnectionProvider.USER_REVISIONS_CACHE_NAME, true);
}
private Configuration getRevisionCacheConfig(boolean managed, long maxEntries) {
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.invocationBatching().enable().transaction().transactionMode(TransactionMode.TRANSACTIONAL);
if (!managed) {
cb.transaction().transactionManagerLookup(new DummyTransactionManagerLookup());
}
cb.transaction().lockingMode(LockingMode.PESSIMISTIC);
cb.eviction().strategy(EvictionStrategy.LRU).type(EvictionType.COUNT).size(maxEntries);
return cb.build();
}
}

View file

@ -25,15 +25,21 @@ import org.keycloak.provider.Provider;
*/
public interface InfinispanConnectionProvider extends Provider {
public static final String VERSION_CACHE_NAME = "realmVersions";
static final String REALM_CACHE_NAME = "realms";
static final String USER_CACHE_NAME = "users";
static final String SESSION_CACHE_NAME = "sessions";
static final String OFFLINE_SESSION_CACHE_NAME = "offlineSessions";
static final String LOGIN_FAILURE_CACHE_NAME = "loginFailures";
static final String WORK_CACHE_NAME = "work";
String REALM_CACHE_NAME = "realms";
String REALM_REVISIONS_CACHE_NAME = "realmRevisions";
int REALM_REVISIONS_CACHE_DEFAULT_MAX = 10000;
String USER_CACHE_NAME = "users";
String USER_REVISIONS_CACHE_NAME = "userRevisions";
int USER_REVISIONS_CACHE_DEFAULT_MAX = 100000;
String SESSION_CACHE_NAME = "sessions";
String OFFLINE_SESSION_CACHE_NAME = "offlineSessions";
String LOGIN_FAILURE_CACHE_NAME = "loginFailures";
String WORK_CACHE_NAME = "work";
String AUTHORIZATION_CACHE_NAME = "authorization";
<K, V> Cache<K, V> getCache(String name);
}

View file

@ -70,7 +70,7 @@ public class CachedPolicyStore implements PolicyStore {
@Override
public void delete(String id) {
getDelegate().delete(id);
this.transaction.whenComplete(() -> cache.remove(id));
this.transaction.whenComplete(() -> cache.remove(getCacheKeyForPolicy(id)));
}
@Override

View file

@ -64,7 +64,7 @@ public class CachedResourceStore implements ResourceStore {
@Override
public void delete(String id) {
this.cache.evict(getCacheKeyForResource(id));
this.cache.remove(getCacheKeyForResource(id));
getDelegate().delete(id);
}

View file

@ -173,6 +173,7 @@ public abstract class CacheManager {
public void clear() {
cache.clear();
revisions.clear();
}
public void addInvalidations(Predicate<Map.Entry<String, Revisioned>> predicate, Set<String> invalidations) {

View file

@ -48,7 +48,7 @@ public class InfinispanCacheRealmProviderFactory implements CacheRealmProviderFa
synchronized (this) {
if (realmCache == null) {
Cache<String, Revisioned> cache = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.REALM_CACHE_NAME);
Cache<String, Long> revisions = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.VERSION_CACHE_NAME);
Cache<String, Long> revisions = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.REALM_REVISIONS_CACHE_NAME);
realmCache = new RealmCacheManager(cache, revisions);
}
}

View file

@ -55,7 +55,7 @@ public class InfinispanCacheUserProviderFactory implements CacheUserProviderFact
synchronized (this) {
if (userCache == null) {
Cache<String, Revisioned> cache = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.USER_CACHE_NAME);
Cache<String, Long> revisions = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.VERSION_CACHE_NAME);
Cache<String, Long> revisions = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.USER_REVISIONS_CACHE_NAME);
userCache = new UserCacheManager(cache, revisions);
}
}

View file

@ -403,6 +403,12 @@ public class RealmAdapter implements RealmModel {
updated.setAccessCodeLifespanLogin(seconds);
}
@Override
public String getKeyId() {
if (isUpdated()) return updated.getKeyId();
return cached.getKeyId();
}
@Override
public String getPublicKeyPem() {
if (isUpdated()) return updated.getPublicKeyPem();

View file

@ -45,6 +45,7 @@ public class UserCacheManager extends CacheManager {
@Override
public void clear() {
cache.clear();
revisions.clear();
}
@Override

View file

@ -94,6 +94,7 @@ public class CachedRealm extends AbstractRevisioned {
protected PasswordPolicy passwordPolicy;
protected OTPPolicy otpPolicy;
protected transient String keyId;
protected transient PublicKey publicKey;
protected String publicKeyPem;
protected transient PrivateKey privateKey;
@ -191,6 +192,7 @@ public class CachedRealm extends AbstractRevisioned {
passwordPolicy = model.getPasswordPolicy();
otpPolicy = model.getOTPPolicy();
keyId = model.getKeyId();
publicKeyPem = model.getPublicKeyPem();
publicKey = model.getPublicKey();
privateKeyPem = model.getPrivateKeyPem();
@ -400,6 +402,10 @@ public class CachedRealm extends AbstractRevisioned {
return accessCodeLifespanLogin;
}
public String getKeyId() {
return keyId;
}
public String getPublicKeyPem() {
return publicKeyPem;
}

View file

@ -20,6 +20,7 @@ package org.keycloak.models.jpa;
import org.jboss.logging.Logger;
import org.keycloak.connections.jpa.util.JpaUtils;
import org.keycloak.common.enums.SslRequired;
import org.keycloak.jose.jwk.JWKBuilder;
import org.keycloak.models.AuthenticationExecutionModel;
import org.keycloak.models.AuthenticationFlowModel;
import org.keycloak.models.AuthenticatorConfigModel;
@ -461,6 +462,12 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
em.flush();
}
@Override
public String getKeyId() {
PublicKey publicKey = getPublicKey();
return publicKey != null ? JWKBuilder.create().rs256(publicKey).getKeyId() : null;
}
@Override
public String getPublicKeyPem() {
return realm.getPublicKeyPem();

View file

@ -22,6 +22,7 @@ import com.mongodb.QueryBuilder;
import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
import org.keycloak.common.enums.SslRequired;
import org.keycloak.jose.jwk.JWKBuilder;
import org.keycloak.models.AuthenticationExecutionModel;
import org.keycloak.models.AuthenticationFlowModel;
import org.keycloak.models.AuthenticatorConfigModel;
@ -455,6 +456,12 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
return realm.getAccessCodeLifespanLogin();
}
@Override
public String getKeyId() {
PublicKey publicKey = getPublicKey();
return publicKey != null ? JWKBuilder.create().rs256(publicKey).getKeyId() : null;
}
@Override
public String getPublicKeyPem() {
return realm.getPublicKeyPem();

View file

@ -26,7 +26,7 @@ public interface MigrationModel {
/**
* Must have the form of major.minor.micro as the version is parsed and numbers are compared
*/
String LATEST_VERSION = "2.0.0";
String LATEST_VERSION = "2.1.0";
String getStoredVersion();
void setStoredVersion(String version);

View file

@ -27,6 +27,7 @@ import org.keycloak.migration.migrators.MigrateTo1_8_0;
import org.keycloak.migration.migrators.MigrateTo1_9_0;
import org.keycloak.migration.migrators.MigrateTo1_9_2;
import org.keycloak.migration.migrators.MigrateTo2_0_0;
import org.keycloak.migration.migrators.MigrateTo2_1_0;
import org.keycloak.migration.migrators.MigrationTo1_2_0_CR1;
import org.keycloak.models.KeycloakSession;
@ -106,6 +107,12 @@ public class MigrationModelManager {
}
new MigrateTo2_0_0().migrate(session);
}
if (stored == null || stored.lessThan(MigrateTo2_1_0.VERSION)) {
if (stored != null) {
logger.debug("Migrating older model to 2.1.0 updates");
}
new MigrateTo2_1_0().migrate(session);
}
model.setStoredVersion(MigrationModel.LATEST_VERSION);
}

View file

@ -17,14 +17,10 @@
package org.keycloak.migration.migrators;
import org.keycloak.Config;
import org.keycloak.migration.ModelVersion;
import org.keycloak.models.AdminRoles;
import org.keycloak.models.ClientModel;
import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.utils.KeycloakModelUtils;
public class MigrateTo2_0_0 {
@ -40,27 +36,8 @@ public class MigrateTo2_0_0 {
private void migrateAuthorizationServices(RealmModel realm) {
KeycloakModelUtils.setupAuthorizationServices(realm);
ClientModel client = realm.getMasterAdminClient();
if (client.getRole(AdminRoles.MANAGE_AUTHORIZATION) == null) {
RoleModel role = client.addRole(AdminRoles.MANAGE_AUTHORIZATION);
role.setDescription("${role_" + AdminRoles.MANAGE_AUTHORIZATION + "}");
role.setScopeParamRequired(false);
client.getRealm().getRole(AdminRoles.ADMIN).addCompositeRole(role);
}
if (!realm.getName().equals(Config.getAdminRealm())) {
client = realm.getClientByClientId(Constants.REALM_MANAGEMENT_CLIENT_ID);
if (client.getRole(AdminRoles.MANAGE_AUTHORIZATION) == null) {
RoleModel role = client.addRole(AdminRoles.MANAGE_AUTHORIZATION);
role.setDescription("${role_" + AdminRoles.MANAGE_AUTHORIZATION + "}");
role.setScopeParamRequired(false);
client.getRole(AdminRoles.REALM_ADMIN).addCompositeRole(role);
}
}
MigrationUtils.addAdminRole(realm, AdminRoles.VIEW_AUTHORIZATION);
MigrationUtils.addAdminRole(realm, AdminRoles.MANAGE_AUTHORIZATION);
}
}

View file

@ -0,0 +1,49 @@
/*
* Copyright 2016 Red Hat Inc. and/or its affiliates and other contributors
* as indicated by the @author tags. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.keycloak.migration.migrators;
import org.keycloak.migration.ModelVersion;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RequiredActionProviderModel;
import org.keycloak.models.UserModel;
/**
*
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
*/
public class MigrateTo2_1_0 {
public static final ModelVersion VERSION = new ModelVersion("2.1.0");
public void migrate(KeycloakSession session) {
for (RealmModel realm : session.realms().getRealms()) {
migrateDefaultRequiredAction(realm);
}
}
// KEYCLOAK-3244: Required Action "Configure Totp" should be "Configure OTP"
private void migrateDefaultRequiredAction(RealmModel realm) {
RequiredActionProviderModel otpAction = realm.getRequiredActionProviderByAlias(UserModel.RequiredAction.CONFIGURE_TOTP.name());
if (otpAction == null) return;
if (!otpAction.getProviderId().equals(UserModel.RequiredAction.CONFIGURE_TOTP.name())) return;
if (!otpAction.getName().equals("Configure Totp")) return;
otpAction.setName("Configure OTP");
}
}

View file

@ -0,0 +1,50 @@
/*
* 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.migration.migrators;
import org.keycloak.Config;
import org.keycloak.models.*;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class MigrationUtils {
public static void addAdminRole(RealmModel realm, String roleName) {
ClientModel client = realm.getMasterAdminClient();
if (client.getRole(roleName) == null) {
RoleModel role = client.addRole(roleName);
role.setDescription("${role_" + roleName + "}");
role.setScopeParamRequired(false);
client.getRealm().getRole(AdminRoles.ADMIN).addCompositeRole(role);
}
if (!realm.getName().equals(Config.getAdminRealm())) {
client = realm.getClientByClientId(Constants.REALM_MANAGEMENT_CLIENT_ID);
if (client.getRole(roleName) == null) {
RoleModel role = client.addRole(roleName);
role.setDescription("${role_" + roleName + "}");
role.setScopeParamRequired(false);
client.getRole(AdminRoles.REALM_ADMIN).addCompositeRole(role);
}
}
}
}

View file

@ -152,6 +152,8 @@ public interface RealmModel extends RoleContainerModel {
void setAccessCodeLifespanLogin(int seconds);
String getKeyId();
String getPublicKeyPem();
void setPublicKeyPem(String publicKeyPem);

View file

@ -52,7 +52,7 @@ public class DefaultRequiredActions {
RequiredActionProviderModel totp = new RequiredActionProviderModel();
totp.setEnabled(true);
totp.setAlias(UserModel.RequiredAction.CONFIGURE_TOTP.name());
totp.setName("Configure Totp");
totp.setName("Configure OTP");
totp.setProviderId(UserModel.RequiredAction.CONFIGURE_TOTP.name());
totp.setDefaultAction(false);
realm.addRequiredActionProvider(totp);

View file

@ -113,7 +113,7 @@ public class UpdateTotp implements RequiredActionProvider, RequiredActionFactory
@Override
public String getDisplayText() {
return "Configure Totp";
return "Configure OTP";
}

View file

@ -99,6 +99,11 @@ public class OIDCLoginProtocolService {
return uriBuilder.path(OIDCLoginProtocolService.class, "token");
}
public static UriBuilder certsUrl(UriBuilder baseUriBuilder) {
UriBuilder uriBuilder = tokenServiceBaseUrl(baseUriBuilder);
return uriBuilder.path(OIDCLoginProtocolService.class, "certs");
}
public static UriBuilder tokenIntrospectionUrl(UriBuilder baseUriBuilder) {
return tokenUrl(baseUriBuilder).path(TokenEndpoint.class, "introspect");
}

View file

@ -78,6 +78,7 @@ import java.util.Set;
*/
public class TokenManager {
protected static final ServicesLogger logger = ServicesLogger.ROOT_LOGGER;
private static final String JWT = "JWT";
public static void applyScope(RoleModel role, RoleModel scope, Set<RoleModel> visited, Set<RoleModel> requested) {
if (visited.contains(scope)) return;
@ -570,6 +571,8 @@ public class TokenManager {
public String encodeToken(RealmModel realm, Object token) {
String encodedToken = new JWSBuilder()
.type(JWT)
.kid(realm.getKeyId())
.jsonContent(token)
.rsa256(realm.getPrivateKey());
return encodedToken;
@ -680,11 +683,11 @@ public class TokenManager {
AccessTokenResponse res = new AccessTokenResponse();
if (idToken != null) {
String encodedToken = new JWSBuilder().jsonContent(idToken).rsa256(realm.getPrivateKey());
String encodedToken = new JWSBuilder().type(JWT).kid(realm.getKeyId()).jsonContent(idToken).rsa256(realm.getPrivateKey());
res.setIdToken(encodedToken);
}
if (accessToken != null) {
String encodedToken = new JWSBuilder().jsonContent(accessToken).rsa256(realm.getPrivateKey());
String encodedToken = new JWSBuilder().type(JWT).kid(realm.getKeyId()).jsonContent(accessToken).rsa256(realm.getPrivateKey());
res.setToken(encodedToken);
res.setTokenType("bearer");
res.setSessionState(accessToken.getSessionState());
@ -693,7 +696,7 @@ public class TokenManager {
}
}
if (refreshToken != null) {
String encodedToken = new JWSBuilder().jsonContent(refreshToken).rsa256(realm.getPrivateKey());
String encodedToken = new JWSBuilder().type(JWT).kid(realm.getKeyId()).jsonContent(refreshToken).rsa256(realm.getPrivateKey());
res.setRefreshToken(encodedToken);
if (refreshToken.getExpiration() != 0) {
res.setRefreshExpiresIn(refreshToken.getExpiration() - Time.currentTime());

View file

@ -40,8 +40,6 @@ import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.resources.Cors;
import org.keycloak.services.Urls;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.OPTIONS;
import javax.ws.rs.POST;
@ -105,9 +103,17 @@ public class UserInfoEndpoint {
@Path("/")
@POST
@NoCache
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces(MediaType.APPLICATION_JSON)
public Response issueUserInfoPost(@FormParam("access_token") String accessToken) {
public Response issueUserInfoPost() {
// Try header first
HttpHeaders headers = request.getHttpHeaders();
String accessToken = this.appAuthManager.extractAuthorizationHeaderToken(headers);
// Fallback to form parameter
if (accessToken == null) {
accessToken = request.getDecodedFormParameters().getFirst("access_token");
}
return issueUserInfo(accessToken);
}

View file

@ -69,13 +69,8 @@ public class RedirectUtils {
private static String verifyRedirectUri(UriInfo uriInfo, String rootUrl, String redirectUri, RealmModel realm, Set<String> validRedirects) {
if (redirectUri == null) {
if (validRedirects.size() != 1) return null;
String validRedirect = validRedirects.iterator().next();
int idx = validRedirect.indexOf("/*");
if (idx > -1) {
validRedirect = validRedirect.substring(0, idx);
}
redirectUri = validRedirect;
logger.debug("No Redirect URI parameter specified");
return null;
} else if (validRedirects.isEmpty()) {
logger.debug("No Redirect URIs supplied");
redirectUri = null;

View file

@ -43,7 +43,7 @@ public class HttpBasicAuthenticator implements AuthenticatorFactory {
@Override
public String getDisplayType() {
return null;
return "HTTP Basic Authentication";
}
@Override
@ -68,7 +68,7 @@ public class HttpBasicAuthenticator implements AuthenticatorFactory {
@Override
public String getHelpText() {
return null;
return "Validates username and password from Authorization HTTP header";
}
@Override

View file

@ -135,6 +135,7 @@ public class LocaleHelper {
private static Locale findLocale(Set<String> supportedLocales, String... localeStrings) {
for (String localeString : localeStrings) {
if (localeString != null) {
Locale result = null;
Locale search = Locale.forLanguageTag(localeString);
for (String languageTag : supportedLocales) {
@ -152,6 +153,7 @@ public class LocaleHelper {
return result;
}
}
}
return null;
}

View file

@ -68,7 +68,7 @@ public class FreeMarkerUtil {
private Template getTemplate(String templateName, Theme theme) throws IOException {
Configuration cfg = new Configuration();
cfg.setTemplateLoader(new ThemeTemplateLoader(theme));
return cfg.getTemplate(templateName);
return cfg.getTemplate(templateName, "UTF-8");
}
class ThemeTemplateLoader extends URLTemplateLoader {

View file

@ -0,0 +1,23 @@
package org.keycloak.services.util;
import org.junit.Test;
import java.lang.reflect.Method;
import java.util.Locale;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.IsNull.nullValue;
public class LocaleHelperTest {
@Test
public void shouldNotExceptionOnNullLocaleAttributeItem() throws Exception {
final Method method = LocaleHelper.class.getDeclaredMethod("findLocale", Set.class, String[].class);
method.setAccessible(true);
Locale foundLocale = (Locale) method.invoke(null, Stream.of("en", "es", "fr").collect(Collectors.toSet()), new String[]{null});
assertThat(foundLocale, nullValue());
}
}

View file

@ -120,13 +120,6 @@ It automatically modifies imported test realms and deployments' adapter configs
| **Relative** | auth server == app server | client `baseUrl`, `adminUrl` and `redirect-uris` can be relative | `auth-server-url` can be relative |
| **Non-relative** | auth server != app server | client `baseUrl`, `adminUrl` and `redirect-uris` need to include FQDN of the app server | `auth-server-url` needs to include FQDN of the auth server|
#### Adapter Libs Mode
1. **Provided** - By container, e.g. as a subsystem. **Default.**
2. **Bundled** - In the deployed war in `/WEB-INF/libs`. Enable with `-Dadapter.libs.bundled`. *Wildfly only*.
#### Adapter Config Mode
1. ~~**Provided** - In `standalone.xml` using `secure-deployment`. *Wildfly only.*~~ WIP

View file

@ -23,14 +23,9 @@ Submodules are enabled with profiles: `-Papp-server-MODULE`
* __`wildfly` Relative Wildfly 10__ Based on [`auth-server/jboss/wildfly`](../auth-server/README.md). Activate with `-Pauth-server-wildfly`.
* __`eap` Relative EAP 7__ Based on [`auth-server/jboss/eap`](../auth-server/README.md). Activate with `-Pauth-server-eap`.
### Adapter Libs Location
* __Provided__ (in container) - Default.
* __Bundled__ (in war) `-Dadapter.libs.bundled=true`
### Adapter Configs Location
* __Provided__ (in standalone.xml as secure-deployment) _Not implemented_
* __Provided__ (in standalone.xml as secure-deployment) WIP
* __Bundled__ (in war) - Default.
### SSL

View file

@ -186,6 +186,24 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<id>install-adapters</id>
<phase>process-test-resources</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>${common.resources}/install-adapters.${script.suffix}</executable>
<workingDirectory>${app.server.jboss.home}/bin</workingDirectory>
<environmentVariables>
<JAVA_HOME>${app.server.java.home}</JAVA_HOME>
<JBOSS_HOME>${app.server.jboss.home}</JBOSS_HOME>
<SAML_SUPPORTED>${app.server.saml.adapter.supported}</SAML_SUPPORTED>
</environmentVariables>
</configuration>
</plugin>
<plugin>
@ -267,45 +285,6 @@
</build>
</profile>
<profile>
<id>adapter-libs-provided</id>
<activation>
<property>
<name>!adapter.libs.bundled</name>
</property>
</activation>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<id>install-adapters</id>
<phase>process-test-resources</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>${common.resources}/install-adapters.${script.suffix}</executable>
<workingDirectory>${app.server.jboss.home}/bin</workingDirectory>
<environmentVariables>
<JAVA_HOME>${app.server.java.home}</JAVA_HOME>
<JBOSS_HOME>${app.server.jboss.home}</JBOSS_HOME>
<SAML_SUPPORTED>${app.server.saml.adapter.supported}</SAML_SUPPORTED>
</environmentVariables>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
<profile>
<id>ssl</id>
<activation>

View file

@ -128,6 +128,10 @@
url = url.replace("http","https");
}
if (window.location.href.indexOf("8180") > -1) {
url = url.replace("8280","8180");
}
var req = new XMLHttpRequest();
req.open('GET', url, true);
req.setRequestHeader('Accept', 'application/json');

View file

@ -1,47 +0,0 @@
/*
* 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.adapter;
/**
*
* @author tkyjovsk
*/
public enum AdapterLibsMode {
PROVIDED("provided"),
BUNDLED("bundled");
private final String type;
private AdapterLibsMode(String type) {
this.type = type;
}
public String getType() {
return type;
}
public static AdapterLibsMode getByType(String type) {
for (AdapterLibsMode s : AdapterLibsMode.values()) {
if (s.getType().equals(type)) {
return s;
}
}
return null;
}
}

View file

@ -8,17 +8,11 @@ import org.jboss.arquillian.core.api.annotation.Observes;
import org.jboss.arquillian.test.spi.annotation.ClassScoped;
import org.jboss.arquillian.test.spi.event.suite.BeforeClass;
import org.jboss.logging.Logger;
import org.keycloak.testsuite.arquillian.annotation.AdapterLibsLocationProperty;
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
import org.keycloak.testsuite.util.LogChecker;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import static org.keycloak.testsuite.util.IOUtil.execCommand;
import static org.keycloak.testsuite.util.WaitUtils.pause;
import static org.keycloak.testsuite.arquillian.AuthServerTestEnricher.getAuthServerContextRoot;
/**
@ -109,66 +103,6 @@ public class AppServerTestEnricher {
}
}
// public void installAdapterLibs(@Observes BeforeDeploy event) {
// log.debug("BEFORE DEPLOY - INSTALL ADAPTER LIBS");
// if (testContext.isAdapterTest()) {
// // install adapter libs on JBoss-based container via CLI
// if (testContext.getAppServerInfo().isJBossBased()) {
// try {
// installAdapterLibsUsingJBossCLIClient(testContext.getAppServerInfo());
// } catch (InterruptedException | IOException ex) {
// throw new RuntimeException("Failed to install adapter libs.", ex);
// }
// }
// }
// }
private void installAdapterLibsUsingJBossCLIClient(ContainerInfo appServerInfo) throws InterruptedException, IOException {
if (!appServerInfo.isAdapterLibsInstalled()) {
if (!appServerInfo.isJBossBased()) {
throw new IllegalArgumentException("App server must be JBoss-based to run jboss-cli-client.");
}
String jbossHomePath = appServerInfo.getProperties().get("jbossHome");
File bin = new File(jbossHomePath + "/bin");
File clientJar = new File(jbossHomePath + "/bin/client/jboss-cli-client.jar");
if (!clientJar.exists()) {
clientJar = new File(jbossHomePath + "/bin/client/jboss-client.jar"); // AS7
}
if (!clientJar.exists()) {
throw new IOException("JBoss CLI client JAR not found.");
}
String command = "java -jar " + clientJar.getAbsolutePath();
String adapterScript = "adapter-install.cli";
String samlAdapterScript = "adapter-install-saml.cli";
String managementPort = appServerInfo.getProperties().get("managementPort");
String controllerArg = " --controller=localhost:" + managementPort;
if (new File(bin, adapterScript).exists()) {
log.info("Installing adapter to app server via cli script");
execCommand(command + " --connect --file=" + adapterScript + controllerArg, bin);
}
if (new File(bin, samlAdapterScript).exists()) {
log.info("Installing saml adapter to app server via cli script");
execCommand(command + " --connect --file=" + samlAdapterScript + controllerArg, bin);
}
if (new File(bin, adapterScript).exists() || new File(bin, samlAdapterScript).exists()) {
log.info("Restarting container");
execCommand(command + " --connect --command=reload" + controllerArg, bin);
log.info("Container restarted");
pause(5000);
if (System.getProperty("app.server.log.check", "true").equals("true")) {
LogChecker.checkJBossServerLog(jbossHomePath);
}
}
appServerInfo.setAdapterLibsInstalled(true);
}
}
/**
*
* @param testClass
@ -190,12 +124,6 @@ public class AppServerTestEnricher {
return getAppServerQualifier(testClass).equals(AuthServerTestEnricher.AUTH_SERVER_CONTAINER);
}
public static String getAdapterLibsLocationProperty(Class testClass) {
Class<? extends AuthServerTestEnricher> annotatedClass = getNearestSuperclassWithAnnotation(testClass, AdapterLibsLocationProperty.class);
return (annotatedClass == null ? "adapter.libs.home"
: annotatedClass.getAnnotation(AdapterLibsLocationProperty.class).value());
}
public static boolean isWildflyAppServer(Class testClass) {
return getAppServerQualifier(testClass).contains("wildfly");
}

View file

@ -25,10 +25,7 @@ import org.jboss.logging.Logger;
import org.jboss.logging.Logger.Level;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.keycloak.representations.adapters.config.AdapterConfig;
import org.keycloak.representations.adapters.config.BaseAdapterConfig;
import org.keycloak.testsuite.adapter.AdapterLibsMode;
import org.keycloak.testsuite.util.IOUtil;
import org.keycloak.util.JsonSerialization;
import org.w3c.dom.Document;
@ -38,7 +35,6 @@ import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import static org.keycloak.testsuite.arquillian.AppServerTestEnricher.getAdapterLibsLocationProperty;
import static org.keycloak.testsuite.arquillian.AppServerTestEnricher.hasAppServerContainerAnnotation;
import static org.keycloak.testsuite.arquillian.AppServerTestEnricher.isRelative;
import static org.keycloak.testsuite.arquillian.AppServerTestEnricher.isTomcatAppServer;
@ -71,7 +67,6 @@ public class DeploymentArchiveProcessor implements ApplicationArchiveProcessor {
log.info("Processing archive " + archive.getName());
// if (isAdapterTest(testClass)) {
modifyAdapterConfigs(archive, testClass);
attachAdapterLibs(archive, testClass);
modifyWebXml(archive, testClass);
// } else {
// log.info(testClass.getJavaClass().getSimpleName() + " is not an AdapterTest");
@ -145,30 +140,6 @@ public class DeploymentArchiveProcessor implements ApplicationArchiveProcessor {
}
}
protected void attachAdapterLibs(Archive<?> archive, TestClass testClass) {
AdapterLibsMode adapterType = AdapterLibsMode.getByType(System.getProperty("adapter.libs.mode",
AdapterLibsMode.PROVIDED.getType()));
log.info("Adapter type: " + adapterType);
if (adapterType.equals(AdapterLibsMode.BUNDLED)) {
log.info("Attaching keycloak adapter libs to " + archive.getName());
String libsLocationProperty = getAdapterLibsLocationProperty(testClass.getJavaClass());
assert libsLocationProperty != null;
File libsLocation = new File(System.getProperty(libsLocationProperty));
assert libsLocation.exists();
log.info("Libs location: " + libsLocation.getPath());
WebArchive war = (WebArchive) archive;
for (File lib : getAdapterLibs(libsLocation)) {
log.info(" attaching: " + lib.getName());
war.addAsLibrary(lib);
}
} else {
log.info("Expecting keycloak adapter libs to be provided by the server.");
}
}
DirectoryScanner scanner = new DirectoryScanner();
protected List<File> getAdapterLibs(File adapterLibsLocation) {

View file

@ -1,36 +0,0 @@
/*
* 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.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Target;
/**
*
* @author tkyjovsk
*/
@Documented
@Retention(RUNTIME)
@Target({ElementType.TYPE})
public @interface AdapterLibsLocationProperty
{
String value() default "adapter.libs.home";
}

View file

@ -33,5 +33,4 @@ import java.lang.annotation.Target;
public @interface AppServerContainer
{
String value() default "";
String adapterLibsLocationProperty() default "";
}

View file

@ -22,6 +22,8 @@ import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.CloseableHttpClient;
@ -34,9 +36,13 @@ import org.keycloak.admin.client.Keycloak;
import org.keycloak.common.VerificationException;
import org.keycloak.common.util.PemUtils;
import org.keycloak.constants.AdapterConstants;
import org.keycloak.jose.jwk.JWK;
import org.keycloak.jose.jwk.JWKBuilder;
import org.keycloak.jose.jwk.JWKParser;
import org.keycloak.jose.jws.JWSInput;
import org.keycloak.jose.jws.crypto.RSAProvider;
import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
import org.keycloak.protocol.oidc.representations.JSONWebKeySet;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.RefreshToken;
import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
@ -279,6 +285,17 @@ public class OAuthClient {
}
}
public JSONWebKeySet doCertsRequest(String realm) throws Exception {
CloseableHttpClient client = new DefaultHttpClient();
try {
HttpGet get = new HttpGet(getCertsUrl(realm));
CloseableHttpResponse response = client.execute(get);
return JsonSerialization.readValue(response.getEntity().getContent(), JSONWebKeySet.class);
} finally {
closeClient(client);
}
}
public AccessTokenResponse doClientCredentialsGrantAccessTokenRequest(String clientSecret) throws Exception {
CloseableHttpClient client = new DefaultHttpClient();
try {
@ -503,6 +520,11 @@ public class OAuthClient {
return b.build(realm).toString();
}
public String getCertsUrl(String realm) {
UriBuilder b = OIDCLoginProtocolService.certsUrl(UriBuilder.fromUri(baseUrl));
return b.build(realm).toString();
}
public String getServiceAccountUrl() {
return getResourceOwnerPasswordCredentialGrantUrl();
}
@ -591,6 +613,7 @@ public class OAuthClient {
public static class AccessTokenResponse {
private int statusCode;
private String idToken;
private String accessToken;
private String tokenType;
private int expiresIn;
@ -610,6 +633,7 @@ public class OAuthClient {
Map responseJson = JsonSerialization.readValue(s, Map.class);
if (statusCode == 200) {
idToken = (String)responseJson.get("id_token");
accessToken = (String)responseJson.get("access_token");
tokenType = (String)responseJson.get("token_type");
expiresIn = (Integer)responseJson.get("expires_in");
@ -624,6 +648,10 @@ public class OAuthClient {
}
}
public String getIdToken() {
return idToken;
}
public String getAccessToken() {
return accessToken;
}

View file

@ -22,6 +22,7 @@ import org.jboss.arquillian.graphene.page.Page;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.testsuite.adapter.AbstractExampleAdapterTest;
@ -39,6 +40,7 @@ import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
/**
* Created by fkiss.
*/
@Ignore //Needs a discussion about future work.
public abstract class AbstractCorsExampleAdapterTest extends AbstractExampleAdapterTest {
public static final String CORS = "cors";

View file

@ -88,6 +88,7 @@ public abstract class AbstractSAMLExampleAdapterTest extends AbstractExampleAdap
waitUntilElement(By.xpath("//body")).text().contains("Welcome to the Sales Tool, " + bburkeUser.getUsername());
samlPostSigExamplePage.logout();
waitUntilElement(By.xpath("//body")).text().contains("Logged out.");
samlPostSigExamplePage.navigateTo();
URLAssert.assertCurrentUrlStartsWith(testRealmSAMLPostLoginPage);
@ -102,6 +103,7 @@ public abstract class AbstractSAMLExampleAdapterTest extends AbstractExampleAdap
waitUntilElement(By.xpath("//body")).text().contains("Welcome to the Sales Tool, " + bburkeUser.getUsername());
samlPostEncExamplePage.logout();
waitUntilElement(By.xpath("//body")).text().contains("Logged out.");
samlPostEncExamplePage.navigateTo();
URLAssert.assertCurrentUrlStartsWith(testRealmSAMLPostLoginPage);
@ -116,6 +118,7 @@ public abstract class AbstractSAMLExampleAdapterTest extends AbstractExampleAdap
waitUntilElement(By.xpath("//body")).text().contains("Welcome to the Employee Tool,");
samlRedirectSigExamplePage.logout();
waitUntilElement(By.xpath("//body")).text().contains("Logged out.");
samlRedirectSigExamplePage.navigateTo();
URLAssert.assertCurrentUrlStartsWith(testRealmSAMLRedirectLoginPage);

View file

@ -614,6 +614,8 @@ public class UserTest extends AbstractAdminTest {
@Test
public void updateUserWithoutUsername() {
switchEditUsernameAllowedOn();
String id = createUser();
@ -674,6 +676,7 @@ public class UserTest extends AbstractAdminTest {
@Test
public void updateUserWithExistingUsername() {
switchEditUsernameAllowedOn();
enableBruteForce();
createUser();
UserRepresentation userRep = new UserRepresentation();
@ -847,4 +850,11 @@ public class UserTest extends AbstractAdminTest {
assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep);
}
private void enableBruteForce() {
RealmRepresentation rep = realm.toRepresentation();
rep.setBruteForceProtected(true);
realm.update(rep);
assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep);
}
}

View file

@ -200,7 +200,7 @@ public class InitialFlowsTest extends AbstractAuthenticationTest {
addExecExport(flow, null, false, "http-basic-authenticator", false, null, REQUIRED, 10);
execs = new LinkedList<>();
addExecInfo(execs, null, "http-basic-authenticator", false, 0, 0, REQUIRED, null, new String[]{});
addExecInfo(execs, "HTTP Basic Authentication", "http-basic-authenticator", false, 0, 0, REQUIRED, null, new String[]{});
expected.add(new FlowExecutions(flow, execs));
return expected;

View file

@ -145,7 +145,7 @@ public class ProvidersTest extends AbstractAuthenticationTest {
"Validates the password supplied as a 'password' form parameter in direct grant request");
addProviderInfo(result, "direct-grant-validate-username", "Username Validation",
"Validates the username supplied as a 'username' form parameter in direct grant request");
addProviderInfo(result, "http-basic-authenticator", null, null);
addProviderInfo(result, "http-basic-authenticator", "HTTP Basic Authentication", "Validates username and password from Authorization HTTP header");
addProviderInfo(result, "idp-confirm-link", "Confirm link existing account", "Show the form where user confirms if he wants " +
"to link identity provider with existing account or rather edit user profile data retrieved from identity provider to avoid conflict");
addProviderInfo(result, "idp-create-user-if-unique", "Create User If Unique", "Detect if there is existing Keycloak account " +

View file

@ -44,7 +44,7 @@ public class RequiredActionsTest extends AbstractAuthenticationTest {
List<RequiredActionProviderRepresentation> result = authMgmtResource.getRequiredActions();
List<RequiredActionProviderRepresentation> expected = new ArrayList<>();
addRequiredAction(expected, "CONFIGURE_TOTP", "Configure Totp", true, false, null);
addRequiredAction(expected, "CONFIGURE_TOTP", "Configure OTP", true, false, null);
addRequiredAction(expected, "UPDATE_PASSWORD", "Update Password", true, false, null);
addRequiredAction(expected, "UPDATE_PROFILE", "Update Profile", true, false, null);
addRequiredAction(expected, "VERIFY_EMAIL", "Verify Email", true, false, null);

View file

@ -32,8 +32,11 @@ import org.keycloak.admin.client.resource.ClientTemplateResource;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.common.enums.SslRequired;
import org.keycloak.common.util.PemUtils;
import org.keycloak.events.Details;
import org.keycloak.events.Errors;
import org.keycloak.jose.jwk.JWKBuilder;
import org.keycloak.jose.jws.JWSHeader;
import org.keycloak.jose.jws.JWSInput;
import org.keycloak.jose.jws.JWSInputException;
import org.keycloak.models.ProtocolMapperModel;
@ -155,6 +158,26 @@ public class AccessTokenTest extends AbstractKeycloakTest {
assertEquals("bearer", response.getTokenType());
String expectedKid = oauth.doCertsRequest("test").getKeys()[0].getKeyId();
JWSHeader header = new JWSInput(response.getAccessToken()).getHeader();
assertEquals("RS256", header.getAlgorithm().name());
assertEquals("JWT", header.getType());
assertEquals(expectedKid, header.getKeyId());
assertNull(header.getContentType());
header = new JWSInput(response.getIdToken()).getHeader();
assertEquals("RS256", header.getAlgorithm().name());
assertEquals("JWT", header.getType());
assertEquals(expectedKid, header.getKeyId());
assertNull(header.getContentType());
header = new JWSInput(response.getRefreshToken()).getHeader();
assertEquals("RS256", header.getAlgorithm().name());
assertEquals("JWT", header.getType());
assertEquals(expectedKid, header.getKeyId());
assertNull(header.getContentType());
AccessToken token = oauth.verifyToken(response.getAccessToken());
assertEquals(findUserByUsername(adminClient.realm("test"), "test-user@localhost").getId(), token.getSubject());

View file

@ -36,6 +36,7 @@ import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.testsuite.AbstractKeycloakTest;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
@ -54,8 +55,11 @@ public class LoginStatusIframeEndpointTest extends AbstractKeycloakTest {
CloseableHttpClient client = HttpClients.custom().setDefaultCookieStore(cookieStore).build();
try {
String redirectUri = URLEncoder.encode(suiteContext.getAuthServerInfo().getContextRoot() + "/auth/admin/master/console", "UTF-8");
HttpGet get = new HttpGet(
suiteContext.getAuthServerInfo().getContextRoot() + "/auth/realms/master/protocol/openid-connect/auth?response_type=code&client_id=" + Constants.ADMIN_CONSOLE_CLIENT_ID);
suiteContext.getAuthServerInfo().getContextRoot() + "/auth/realms/master/protocol/openid-connect/auth?response_type=code&client_id=" + Constants.ADMIN_CONSOLE_CLIENT_ID +
"&redirect_uri=" + redirectUri);
CloseableHttpResponse response = client.execute(get);
String s = IOUtils.toString(response.getEntity().getContent());

View file

@ -103,9 +103,9 @@ public class OAuthRedirectUriTest extends AbstractKeycloakTest {
@Test
public void testNoParam() throws IOException {
oauth.redirectUri(null);
OAuthClient.AuthorizationCodeResponse response = oauth.doLogin("test-user@localhost", "password");
Assert.assertNotNull(response.getCode());
assertEquals(oauth.getCurrentRequest(), APP_ROOT + "/auth");
oauth.openLoginForm();
Assert.assertTrue(errorPage.isCurrent());
Assert.assertEquals("Invalid parameter: redirect_uri", errorPage.getError());
}
@Test

View file

@ -75,57 +75,120 @@ public class UserInfoTest extends AbstractKeycloakTest {
}
@Test
public void testSuccessfulUserInfoRequest() throws Exception {
public void testSuccess_getMethod_bearer() throws Exception {
Client client = ClientBuilder.newClient();
UriBuilder builder = UriBuilder.fromUri(AUTH_SERVER_ROOT);
URI grantUri = OIDCLoginProtocolService.tokenUrl(builder).build("test");
WebTarget grantTarget = client.target(grantUri);
AccessTokenResponse accessTokenResponse = executeGrantAccessTokenRequest(grantTarget);
Response response = executeUserInfoRequest(accessTokenResponse.getToken());
assertEquals(Status.OK.getStatusCode(), response.getStatus());
try {
AccessTokenResponse accessTokenResponse = executeGrantAccessTokenRequest(client);
Response response = executeUserInfoRequest_getMethod(client, accessTokenResponse.getToken());
UserInfo userInfo = response.readEntity(UserInfo.class);
response.close();
assertNotNull(userInfo);
assertNotNull(userInfo.getSubject());
assertEquals("test-user@localhost", userInfo.getEmail());
assertEquals("test-user@localhost", userInfo.getPreferredUsername());
testSuccessfulUserInfoResponse(response);
} finally {
client.close();
}
}
@Test
public void testSuccess_postMethod_bearer() throws Exception {
Client client = ClientBuilder.newClient();
try {
AccessTokenResponse accessTokenResponse = executeGrantAccessTokenRequest(client);
WebTarget userInfoTarget = getUserInfoWebTarget(client);
Response response = userInfoTarget.request()
.header(HttpHeaders.AUTHORIZATION, "bearer " + accessTokenResponse.getToken())
.post(Entity.form(new Form()));
testSuccessfulUserInfoResponse(response);
} finally {
client.close();
}
}
@Test
public void testSuccess_postMethod_body() throws Exception {
Client client = ClientBuilder.newClient();
try {
AccessTokenResponse accessTokenResponse = executeGrantAccessTokenRequest(client);
Form form = new Form();
form.param("access_token", accessTokenResponse.getToken());
WebTarget userInfoTarget = getUserInfoWebTarget(client);
Response response = userInfoTarget.request()
.post(Entity.form(form));
testSuccessfulUserInfoResponse(response);
} finally {
client.close();
}
}
@Test
public void testSuccess_postMethod_bearer_textEntity() throws Exception {
Client client = ClientBuilder.newClient();
try {
AccessTokenResponse accessTokenResponse = executeGrantAccessTokenRequest(client);
WebTarget userInfoTarget = getUserInfoWebTarget(client);
Response response = userInfoTarget.request()
.header(HttpHeaders.AUTHORIZATION, "bearer " + accessTokenResponse.getToken())
.post(Entity.text(""));
testSuccessfulUserInfoResponse(response);
} finally {
client.close();
}
}
@Test
public void testSessionExpired() throws Exception {
Client client = ClientBuilder.newClient();
UriBuilder builder = UriBuilder.fromUri(AUTH_SERVER_ROOT);
URI grantUri = OIDCLoginProtocolService.tokenUrl(builder).build("test");
WebTarget grantTarget = client.target(grantUri);
AccessTokenResponse accessTokenResponse = executeGrantAccessTokenRequest(grantTarget);
try {
AccessTokenResponse accessTokenResponse = executeGrantAccessTokenRequest(client);
testingClient.testing().removeUserSessions("test");
Response response = executeUserInfoRequest(accessTokenResponse.getToken());
Response response = executeUserInfoRequest_getMethod(client, accessTokenResponse.getToken());
assertEquals(Status.FORBIDDEN.getStatusCode(), response.getStatus());
response.close();
} finally {
client.close();
}
}
@Test
public void testUnsuccessfulUserInfoRequest() throws Exception {
Response response = executeUserInfoRequest("bad");
Client client = ClientBuilder.newClient();
try {
Response response = executeUserInfoRequest_getMethod(client, "bad");
response.close();
assertEquals(Status.FORBIDDEN.getStatusCode(), response.getStatus());
} finally {
client.close();
}
}
private AccessTokenResponse executeGrantAccessTokenRequest(WebTarget grantTarget) {
private AccessTokenResponse executeGrantAccessTokenRequest(Client client) {
UriBuilder builder = UriBuilder.fromUri(AUTH_SERVER_ROOT);
URI grantUri = OIDCLoginProtocolService.tokenUrl(builder).build("test");
WebTarget grantTarget = client.target(grantUri);
String header = BasicAuthHelper.createHeader("test-app", "password");
Form form = new Form();
form.param(OAuth2Constants.GRANT_TYPE, OAuth2Constants.PASSWORD)
@ -145,15 +208,31 @@ public class UserInfoTest extends AbstractKeycloakTest {
return accessTokenResponse;
}
private Response executeUserInfoRequest(String accessToken) {
UriBuilder builder = UriBuilder.fromUri(AUTH_SERVER_ROOT);
UriBuilder uriBuilder = OIDCLoginProtocolService.tokenServiceBaseUrl(builder);
URI userInfoUri = uriBuilder.path(OIDCLoginProtocolService.class, "issueUserInfo").build("test");
Client client = ClientBuilder.newClient();
WebTarget userInfoTarget = client.target(userInfoUri);
private Response executeUserInfoRequest_getMethod(Client client, String accessToken) {
WebTarget userInfoTarget = getUserInfoWebTarget(client);
return userInfoTarget.request()
.header(HttpHeaders.AUTHORIZATION, "bearer " + accessToken)
.get();
}
private WebTarget getUserInfoWebTarget(Client client) {
UriBuilder builder = UriBuilder.fromUri(AUTH_SERVER_ROOT);
UriBuilder uriBuilder = OIDCLoginProtocolService.tokenServiceBaseUrl(builder);
URI userInfoUri = uriBuilder.path(OIDCLoginProtocolService.class, "issueUserInfo").build("test");
return client.target(userInfoUri);
}
private void testSuccessfulUserInfoResponse(Response response) {
assertEquals(Status.OK.getStatusCode(), response.getStatus());
UserInfo userInfo = response.readEntity(UserInfo.class);
response.close();
assertNotNull(userInfo);
assertNotNull(userInfo.getSubject());
assertEquals("test-user@localhost", userInfo.getEmail());
assertEquals("test-user@localhost", userInfo.getPreferredUsername());
}
}

View file

@ -33,7 +33,6 @@
<properties>
<app.server>as7</app.server>
<adapter.libs.home>${app.server.home}/modules/org/keycloak</adapter.libs.home>
<app.server.management.protocol>remote</app.server.management.protocol>
<app.server.management.port>${app.server.management.port.jmx}</app.server.management.port>

View file

@ -8,7 +8,6 @@ import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
* @author tkyjovsk
*/
@AppServerContainer("app-server-as7")
//@AdapterLibsLocationProperty("adapter.libs.as7")
public class AS7OIDCAdapterTest extends AbstractDemoServletsAdapterTest {
}

View file

@ -8,7 +8,6 @@ import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
* @author tkyjovsk
*/
@AppServerContainer("app-server-as7")
//@AdapterLibsLocationProperty("adapter.libs.as7")
public class AS7OIDCSessionAdapterTest extends AbstractSessionServletAdapterTest {
}

View file

@ -7,7 +7,6 @@ import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
* @author tkyjovsk
*/
@AppServerContainer("app-server-as7")
//@AdapterLibsLocationProperty("adapter.libs.as7")
public class AS7BasicAuthExampleAdapterTest extends AbstractBasicAuthExampleAdapterTest {
}

View file

@ -7,7 +7,6 @@ import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
* @author tkyjovsk
*/
@AppServerContainer("app-server-as7")
//@AdapterLibsLocationProperty("adapter.libs.as7")
public class AS7DemoExampleAdapterTest extends AbstractDemoExampleAdapterTest {
}

View file

@ -1,7 +1,6 @@
package org.keycloak.testsuite.adapter;
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
import org.junit.Ignore;
import org.keycloak.testsuite.adapter.servlet.AbstractDemoServletsAdapterTest;
/**
@ -9,8 +8,6 @@ import org.keycloak.testsuite.adapter.servlet.AbstractDemoServletsAdapterTest;
* @author tkyjovsk
*/
@AppServerContainer("app-server-eap")
//@AdapterLibsLocationProperty("adapter.libs.eap7")
//@Ignore //failing tests
public class EAPOIDCAdapterTest extends AbstractDemoServletsAdapterTest {
}

View file

@ -8,7 +8,6 @@ import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
* @author tkyjovsk
*/
@AppServerContainer("app-server-eap")
//@AdapterLibsLocationProperty("adapter.libs.eap7")
public class EAPOIDCSessionAdapterTest extends AbstractSessionServletAdapterTest {
}

View file

@ -7,7 +7,6 @@ import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
* @author mhajas
*/
@AppServerContainer("app-server-eap")
//@AdapterLibsLocationProperty("adapter.libs.eap7")
public class EAPSAMLAdapterTest extends AbstractSAMLServletsAdapterTest {
}

View file

@ -7,7 +7,6 @@ import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
* @author tkyjovsk
*/
@AppServerContainer("app-server-eap")
//@AdapterLibsLocationProperty("adapter.libs.eap7")
public class EAPBasicAuthExampleAdapterTest extends AbstractBasicAuthExampleAdapterTest {
}

View file

@ -7,7 +7,6 @@ import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
* @author tkyjovsk
*/
@AppServerContainer("app-server-eap")
//@AdapterLibsLocationProperty("adapter.libs.eap7")
public class EAPDemoExampleAdapterTest extends AbstractDemoExampleAdapterTest {
}

View file

@ -1,13 +1,11 @@
package org.keycloak.testsuite.adapter.example;
import org.keycloak.testsuite.arquillian.annotation.AdapterLibsLocationProperty;
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
import org.junit.Ignore;
/**
* @author tkyjovsk
*/
@AppServerContainer("app-server-eap")
//@AdapterLibsLocationProperty("adapter.libs.eap")
public class EAPJSConsoleExampleAdapterTest extends AbstractJSConsoleExampleAdapterTest {
}

View file

@ -6,7 +6,6 @@ import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
* @author mhajas
*/
@AppServerContainer("app-server-eap")
//@AdapterLibsLocationProperty("adapter.libs.eap7")
public class EAPSAMLExampleAdapterTest extends AbstractSAMLExampleAdapterTest {
}

View file

@ -1,7 +1,6 @@
package org.keycloak.testsuite.adapter;
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
import org.junit.Ignore;
import org.keycloak.testsuite.adapter.servlet.AbstractDemoServletsAdapterTest;
/**
@ -9,8 +8,6 @@ import org.keycloak.testsuite.adapter.servlet.AbstractDemoServletsAdapterTest;
* @author tkyjovsk
*/
@AppServerContainer("app-server-eap6")
//@AdapterLibsLocationProperty("adapter.libs.eap6")
//@Ignore //failing tests
public class EAP6OIDCAdapterTest extends AbstractDemoServletsAdapterTest {
}

View file

@ -8,7 +8,6 @@ import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
* @author tkyjovsk
*/
@AppServerContainer("app-server-eap6")
//@AdapterLibsLocationProperty("adapter.libs.eap6")
public class EAP6OIDCSessionAdapterTest extends AbstractSessionServletAdapterTest {
}

View file

@ -7,7 +7,6 @@ import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
* @author mhajas
*/
@AppServerContainer("app-server-eap6")
//@AdapterLibsLocationProperty("adapter.libs.eap6")
public class EAP6SAMLAdapterTest extends AbstractSAMLServletsAdapterTest {
}

View file

@ -7,7 +7,6 @@ import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
* @author tkyjovsk
*/
@AppServerContainer("app-server-eap6")
//@AdapterLibsLocationProperty("adapter.libs.eap6")
public class EAP6BasicAuthExampleAdapterTest extends AbstractBasicAuthExampleAdapterTest {
}

View file

@ -7,7 +7,6 @@ import org.junit.Ignore;
* @author fkiss
*/
@AppServerContainer("app-server-eap6")
//@AdapterLibsLocationProperty("adapter.libs.eap6")
@Ignore //cannot find web.xml in target/examples
public class EAP6CorsExampleAdapterTest extends AbstractCorsExampleAdapterTest {

View file

@ -7,7 +7,6 @@ import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
* @author tkyjovsk
*/
@AppServerContainer("app-server-eap6")
//@AdapterLibsLocationProperty("adapter.libs.eap6")
public class EAP6DemoExampleAdapterTest extends AbstractDemoExampleAdapterTest {
}

View file

@ -1,13 +1,11 @@
package org.keycloak.testsuite.adapter.example;
import org.keycloak.testsuite.arquillian.annotation.AdapterLibsLocationProperty;
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
import org.junit.Ignore;
/**
* @author tkyjovsk
*/
@AppServerContainer("app-server-eap6")
//@AdapterLibsLocationProperty("adapter.libs.eap6")
public class EAP6JSConsoleExampleAdapterTest extends AbstractJSConsoleExampleAdapterTest {
}

View file

@ -6,7 +6,6 @@ import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
* @author mhajas
*/
@AppServerContainer("app-server-eap6")
//@AdapterLibsLocationProperty("adapter.libs.eap6")
public class EAP6SAMLExampleAdapterTest extends AbstractSAMLExampleAdapterTest {
}

View file

@ -35,7 +35,6 @@
<properties>
<common.resources>${project.parent.basedir}/common</common.resources>
<adapter.libs.home>${app.server.home}/modules/system/add-ons/keycloak</adapter.libs.home>
<app.server.type>managed</app.server.type>
</properties>
@ -46,7 +45,7 @@
<artifactId>xml-maven-plugin</artifactId>
<executions>
<execution>
<id>Configure keycloak subsystem</id>
<id>configure-keycloak-subsystem</id>
<phase>process-test-resources</phase>
<goals>
<goal>transform</goal>
@ -91,7 +90,7 @@
<artifactId>xml-maven-plugin</artifactId>
<executions>
<execution>
<id>Configure keycloak subsystem</id>
<id>configure-keycloak-subsystem</id>
<phase>process-test-resources</phase>
<goals>
<goal>transform</goal>

View file

@ -6,7 +6,6 @@ import org.keycloak.testsuite.adapter.servlet.AbstractDemoServletsAdapterTest;
*
* @author tkyjovsk
*/
//@AdapterLibsLocationProperty("adapter.libs.eap")
public class RelativeEAPOIDCAdapterTest extends AbstractDemoServletsAdapterTest {
}

View file

@ -6,7 +6,6 @@ import org.keycloak.testsuite.adapter.servlet.AbstractSessionServletAdapterTest;
*
* @author tkyjovsk
*/
//@AdapterLibsLocationProperty("adapter.libs.eap")
public class RelativeEAPOIDCSessionAdapterTest extends AbstractSessionServletAdapterTest {
}

View file

@ -5,7 +5,6 @@ import org.keycloak.testsuite.adapter.servlet.AbstractSAMLServletsAdapterTest;
/**
* @author mhajas
*/
//@AdapterLibsLocationProperty("adapter.libs.eap")
public class RelativeEAPSAMLAdapterTest extends AbstractSAMLServletsAdapterTest {
}

View file

@ -4,7 +4,6 @@ package org.keycloak.testsuite.adapter.example;
*
* @author tkyjovsk
*/
//@AdapterLibsLocationProperty("adapter.libs.eap")
public class RelativeEAPBasicAuthExampleAdapterTest extends AbstractBasicAuthExampleAdapterTest {
}

View file

@ -4,7 +4,6 @@ package org.keycloak.testsuite.adapter.example;
*
* @author fkiss
*/
//@AdapterLibsLocationProperty("adapter.libs.eap")
public class RelativeEAPCorsExampleAdapterTest extends AbstractCorsExampleAdapterTest {
}

View file

@ -4,7 +4,6 @@ package org.keycloak.testsuite.adapter.example;
*
* @author tkyjovsk
*/
//@AdapterLibsLocationProperty("adapter.libs.eap")
public class RelativeEAPDemoExampleAdapterTest extends AbstractDemoExampleAdapterTest {
}

View file

@ -4,7 +4,6 @@ package org.keycloak.testsuite.adapter.example;
*
* @author tkyjovsk
*/
//@AdapterLibsLocationProperty("adapter.libs.eap")
public class RelativeEAPJSConsoleExampleAdapterTest extends AbstractJSConsoleExampleAdapterTest {
}

View file

@ -4,7 +4,6 @@ package org.keycloak.testsuite.adapter.example;
*
* @author mhajas
*/
//@AdapterLibsLocationProperty("adapter.libs.eap")
public class RelativeEAPSAMLExampleAdapterTest extends AbstractSAMLExampleAdapterTest {
}

View file

@ -6,7 +6,6 @@ import org.keycloak.testsuite.adapter.servlet.AbstractDemoServletsAdapterTest;
*
* @author tkyjovsk
*/
//@AdapterLibsLocationProperty("adapter.libs.eap")
public class RelativeWildflyOIDCAdapterTest extends AbstractDemoServletsAdapterTest {
}

View file

@ -6,7 +6,6 @@ import org.keycloak.testsuite.adapter.servlet.AbstractSessionServletAdapterTest;
*
* @author tkyjovsk
*/
//@AdapterLibsLocationProperty("adapter.libs.eap")
public class RelativeWildflyOIDCSessionAdapterTest extends AbstractSessionServletAdapterTest {
}

View file

@ -5,7 +5,6 @@ import org.keycloak.testsuite.adapter.servlet.AbstractSAMLServletsAdapterTest;
/**
* @author mhajas
*/
//@AdapterLibsLocationProperty("adapter.libs.eap")
public class RelativeWildflySAMLAdapterTest extends AbstractSAMLServletsAdapterTest {
}

View file

@ -4,7 +4,6 @@ package org.keycloak.testsuite.adapter.example;
*
* @author tkyjovsk
*/
//@AdapterLibsLocationProperty("adapter.libs.eap")
public class RelativeWildflyBasicAuthExampleAdapterTest extends AbstractBasicAuthExampleAdapterTest {
}

View file

@ -4,7 +4,6 @@ package org.keycloak.testsuite.adapter.example;
*
* @author fkiss
*/
//@AdapterLibsLocationProperty("adapter.libs.eap")
public class RelativeWildflyCorsExampleAdapterTest extends AbstractCorsExampleAdapterTest {
}

View file

@ -4,7 +4,6 @@ package org.keycloak.testsuite.adapter.example;
*
* @author tkyjovsk
*/
//@AdapterLibsLocationProperty("adapter.libs.eap")
public class RelativeWildflyDemoExampleAdapterTest extends AbstractDemoExampleAdapterTest {
}

View file

@ -4,7 +4,6 @@ package org.keycloak.testsuite.adapter.example;
*
* @author tkyjovsk
*/
//@AdapterLibsLocationProperty("adapter.libs.eap")
public class RelativeWildflyJSConsoleExampleAdapterTest extends AbstractJSConsoleExampleAdapterTest {
}

View file

@ -4,7 +4,6 @@ package org.keycloak.testsuite.adapter.example;
*
* @author mhajas
*/
//@AdapterLibsLocationProperty("adapter.libs.eap")
public class RelativeWildflySAMLExampleAdapterTest extends AbstractSAMLExampleAdapterTest {
}

View file

@ -8,7 +8,6 @@ import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
* @author tkyjovsk
*/
@AppServerContainer("app-server-wildfly")
//@AdapterLibsLocationProperty("adapter.libs.wildfly")
public class WildflyOIDCAdapterTest extends AbstractDemoServletsAdapterTest {
}

View file

@ -8,7 +8,6 @@ import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
* @author tkyjovsk
*/
@AppServerContainer("app-server-wildfly")
//@AdapterLibsLocationProperty("adapter.libs.wildfly")
public class WildflyOIDCSessionAdapterTest extends AbstractSessionServletAdapterTest {
}

View file

@ -7,7 +7,6 @@ import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
* @author mhajas
*/
@AppServerContainer("app-server-wildfly")
//@AdapterLibsLocationProperty("adapter.libs.wildfly")
public class WildflySAMLAdapterTest extends AbstractSAMLServletsAdapterTest {
}

View file

@ -7,7 +7,6 @@ import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
* @author tkyjovsk
*/
@AppServerContainer("app-server-wildfly")
//@AdapterLibsLocationProperty("adapter.libs.wildfly")
public class WildflyBasicAuthExampleAdapterTest extends AbstractBasicAuthExampleAdapterTest {
}

View file

@ -7,7 +7,6 @@ import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
* @author tkyjovsk
*/
@AppServerContainer("app-server-wildfly")
//@AdapterLibsLocationProperty("adapter.libs.wildfly")
public class WildflyDemoExampleAdapterTest extends AbstractDemoExampleAdapterTest {
}

View file

@ -1,16 +1,13 @@
package org.keycloak.testsuite.adapter.example;
import org.keycloak.testsuite.arquillian.annotation.AdapterLibsLocationProperty;
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
/**
*
* @author tkyjovsk
*/
@AppServerContainer("app-server-wildfly")
//@AdapterLibsLocationProperty("adapter.libs.wildfly")
public class WildflyJSConsoleExampleAdapterTest extends AbstractJSConsoleExampleAdapterTest {
}

View file

@ -6,7 +6,6 @@ import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
* @author mhajas
*/
@AppServerContainer("app-server-wildfly")
//@AdapterLibsLocationProperty("adapter.libs.wildfly")
public class WildflySAMLExampleAdapterTest extends AbstractSAMLExampleAdapterTest {
}

View file

@ -8,7 +8,6 @@ import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
* @author tkyjovsk
*/
@AppServerContainer("app-server-wildfly8")
//@AdapterLibsLocationProperty("adapter.libs.wildfly8")
public class Wildfly8OIDCAdapterTest extends AbstractDemoServletsAdapterTest {
}

Some files were not shown because too many files have changed in this diff Show more