Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
0040d3fc3b
127 changed files with 1936 additions and 649 deletions
|
@ -25,7 +25,7 @@
|
|||
var kc = this;
|
||||
var adapter;
|
||||
var refreshQueue = [];
|
||||
var storage;
|
||||
var callbackStorage;
|
||||
|
||||
var loginIframe = {
|
||||
enable: true,
|
||||
|
@ -36,10 +36,10 @@
|
|||
kc.init = function (initOptions) {
|
||||
kc.authenticated = false;
|
||||
|
||||
storage = new PersistentStorage();
|
||||
callbackStorage = createCallbackStorage();
|
||||
|
||||
if (initOptions && initOptions.adapter === 'cordova') {
|
||||
adapter = loadAdapter('cordova');
|
||||
adapter = loadAdapter('cordova');
|
||||
} else if (initOptions && initOptions.adapter === 'default') {
|
||||
adapter = loadAdapter();
|
||||
} else {
|
||||
|
@ -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;
|
||||
}
|
||||
var data = JSON.parse(event.data);
|
||||
|
||||
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 PersistentStorage = function() {
|
||||
if (!(this instanceof PersistentStorage)) {
|
||||
return new PersistentStorage();
|
||||
var LocalStorage = function() {
|
||||
if (!(this instanceof LocalStorage)) {
|
||||
return new LocalStorage();
|
||||
}
|
||||
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 expires = JSON.parse(value).expires;
|
||||
if (!expires || expires < time) {
|
||||
localStorage.removeItem(key);
|
||||
}
|
||||
} catch (err) {
|
||||
localStorage.removeItem(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
var key = '@@keycloak-session-storage/test';
|
||||
localStorage.setItem(key, 'test');
|
||||
}
|
||||
|
||||
cs.get = function(state) {
|
||||
if (!state) {
|
||||
return;
|
||||
}
|
||||
|
||||
var key = 'kc-callback-' + state;
|
||||
var value = localStorage.getItem(key);
|
||||
if (value) {
|
||||
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;
|
||||
value = JSON.parse(value);
|
||||
}
|
||||
}
|
||||
|
||||
ps.setItem = function(key, value) {
|
||||
if (useCookieStorage()) {
|
||||
setCookie(key, value, cookieExpiration(5));
|
||||
} else {
|
||||
localStorage.setItem(key, value);
|
||||
}
|
||||
}
|
||||
clearExpired();
|
||||
return value;
|
||||
};
|
||||
|
||||
ps.getItem = function(key) {
|
||||
if (useCookieStorage()) {
|
||||
return getCookie(key);
|
||||
}
|
||||
return localStorage.getItem(key);
|
||||
}
|
||||
cs.add = function(state) {
|
||||
clearExpired();
|
||||
|
||||
ps.removeItem = function(key) {
|
||||
if (typeof localStorage !== "undefined") {
|
||||
try {
|
||||
// Always try to delete from localStorage.
|
||||
localStorage.removeItem(key);
|
||||
} catch (err) { }
|
||||
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;
|
||||
}
|
||||
// Always remove the cookie.
|
||||
|
||||
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) {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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)
|
|
@ -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.
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -45,6 +45,7 @@ public class UserCacheManager extends CacheManager {
|
|||
@Override
|
||||
public void clear() {
|
||||
cache.clear();
|
||||
revisions.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -152,6 +152,8 @@ public interface RealmModel extends RoleContainerModel {
|
|||
|
||||
void setAccessCodeLifespanLogin(int seconds);
|
||||
|
||||
String getKeyId();
|
||||
|
||||
String getPublicKeyPem();
|
||||
|
||||
void setPublicKeyPem(String publicKeyPem);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -113,7 +113,7 @@ public class UpdateTotp implements RequiredActionProvider, RequiredActionFactory
|
|||
|
||||
@Override
|
||||
public String getDisplayText() {
|
||||
return "Configure Totp";
|
||||
return "Configure OTP";
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -135,21 +135,23 @@ public class LocaleHelper {
|
|||
|
||||
private static Locale findLocale(Set<String> supportedLocales, String... localeStrings) {
|
||||
for (String localeString : localeStrings) {
|
||||
Locale result = null;
|
||||
Locale search = Locale.forLanguageTag(localeString);
|
||||
for (String languageTag : supportedLocales) {
|
||||
Locale locale = Locale.forLanguageTag(languageTag);
|
||||
if (locale.getLanguage().equals(search.getLanguage())) {
|
||||
if (locale.getCountry().equals("") && result == null) {
|
||||
result = locale;
|
||||
}
|
||||
if (locale.getCountry().equals(search.getCountry())) {
|
||||
return locale;
|
||||
if (localeString != null) {
|
||||
Locale result = null;
|
||||
Locale search = Locale.forLanguageTag(localeString);
|
||||
for (String languageTag : supportedLocales) {
|
||||
Locale locale = Locale.forLanguageTag(languageTag);
|
||||
if (locale.getLanguage().equals(search.getLanguage())) {
|
||||
if (locale.getCountry().equals("") && result == null) {
|
||||
result = locale;
|
||||
}
|
||||
if (locale.getCountry().equals(search.getCountry())) {
|
||||
return locale;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result != null) {
|
||||
return result;
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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";
|
||||
}
|
|
@ -33,5 +33,4 @@ import java.lang.annotation.Target;
|
|||
public @interface AppServerContainer
|
||||
{
|
||||
String value() default "";
|
||||
String adapterLibsLocationProperty() default "";
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 " +
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
testSuccessfulUserInfoResponse(response);
|
||||
|
||||
response.close();
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
|
||||
assertNotNull(userInfo);
|
||||
assertNotNull(userInfo.getSubject());
|
||||
assertEquals("test-user@localhost", userInfo.getEmail());
|
||||
assertEquals("test-user@localhost", userInfo.getPreferredUsername());
|
||||
@Test
|
||||
public void testSuccess_postMethod_bearer() throws Exception {
|
||||
Client client = ClientBuilder.newClient();
|
||||
|
||||
client.close();
|
||||
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);
|
||||
|
||||
testingClient.testing().removeUserSessions("test");
|
||||
try {
|
||||
AccessTokenResponse accessTokenResponse = executeGrantAccessTokenRequest(client);
|
||||
|
||||
Response response = executeUserInfoRequest(accessTokenResponse.getToken());
|
||||
testingClient.testing().removeUserSessions("test");
|
||||
|
||||
assertEquals(Status.FORBIDDEN.getStatusCode(), response.getStatus());
|
||||
Response response = executeUserInfoRequest_getMethod(client, accessTokenResponse.getToken());
|
||||
|
||||
response.close();
|
||||
assertEquals(Status.FORBIDDEN.getStatusCode(), response.getStatus());
|
||||
|
||||
client.close();
|
||||
response.close();
|
||||
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnsuccessfulUserInfoRequest() throws Exception {
|
||||
Response response = executeUserInfoRequest("bad");
|
||||
Client client = ClientBuilder.newClient();
|
||||
|
||||
response.close();
|
||||
try {
|
||||
Response response = executeUserInfoRequest_getMethod(client, "bad");
|
||||
|
||||
assertEquals(Status.FORBIDDEN.getStatusCode(), response.getStatus());
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 {
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
}
|
|
@ -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 {
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
}
|
|
@ -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 {
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
}
|
|
@ -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 {
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
||||
}
|
|
@ -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 {
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
}
|
|
@ -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>
|
||||
|
|
|
@ -6,7 +6,6 @@ import org.keycloak.testsuite.adapter.servlet.AbstractDemoServletsAdapterTest;
|
|||
*
|
||||
* @author tkyjovsk
|
||||
*/
|
||||
//@AdapterLibsLocationProperty("adapter.libs.eap")
|
||||
public class RelativeEAPOIDCAdapterTest extends AbstractDemoServletsAdapterTest {
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import org.keycloak.testsuite.adapter.servlet.AbstractSessionServletAdapterTest;
|
|||
*
|
||||
* @author tkyjovsk
|
||||
*/
|
||||
//@AdapterLibsLocationProperty("adapter.libs.eap")
|
||||
public class RelativeEAPOIDCSessionAdapterTest extends AbstractSessionServletAdapterTest {
|
||||
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import org.keycloak.testsuite.adapter.servlet.AbstractSAMLServletsAdapterTest;
|
|||
/**
|
||||
* @author mhajas
|
||||
*/
|
||||
//@AdapterLibsLocationProperty("adapter.libs.eap")
|
||||
public class RelativeEAPSAMLAdapterTest extends AbstractSAMLServletsAdapterTest {
|
||||
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ package org.keycloak.testsuite.adapter.example;
|
|||
*
|
||||
* @author tkyjovsk
|
||||
*/
|
||||
//@AdapterLibsLocationProperty("adapter.libs.eap")
|
||||
public class RelativeEAPBasicAuthExampleAdapterTest extends AbstractBasicAuthExampleAdapterTest {
|
||||
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ package org.keycloak.testsuite.adapter.example;
|
|||
*
|
||||
* @author fkiss
|
||||
*/
|
||||
//@AdapterLibsLocationProperty("adapter.libs.eap")
|
||||
public class RelativeEAPCorsExampleAdapterTest extends AbstractCorsExampleAdapterTest {
|
||||
|
||||
}
|
|
@ -4,7 +4,6 @@ package org.keycloak.testsuite.adapter.example;
|
|||
*
|
||||
* @author tkyjovsk
|
||||
*/
|
||||
//@AdapterLibsLocationProperty("adapter.libs.eap")
|
||||
public class RelativeEAPDemoExampleAdapterTest extends AbstractDemoExampleAdapterTest {
|
||||
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ package org.keycloak.testsuite.adapter.example;
|
|||
*
|
||||
* @author tkyjovsk
|
||||
*/
|
||||
//@AdapterLibsLocationProperty("adapter.libs.eap")
|
||||
public class RelativeEAPJSConsoleExampleAdapterTest extends AbstractJSConsoleExampleAdapterTest {
|
||||
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ package org.keycloak.testsuite.adapter.example;
|
|||
*
|
||||
* @author mhajas
|
||||
*/
|
||||
//@AdapterLibsLocationProperty("adapter.libs.eap")
|
||||
public class RelativeEAPSAMLExampleAdapterTest extends AbstractSAMLExampleAdapterTest {
|
||||
|
||||
}
|
|
@ -6,7 +6,6 @@ import org.keycloak.testsuite.adapter.servlet.AbstractDemoServletsAdapterTest;
|
|||
*
|
||||
* @author tkyjovsk
|
||||
*/
|
||||
//@AdapterLibsLocationProperty("adapter.libs.eap")
|
||||
public class RelativeWildflyOIDCAdapterTest extends AbstractDemoServletsAdapterTest {
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import org.keycloak.testsuite.adapter.servlet.AbstractSessionServletAdapterTest;
|
|||
*
|
||||
* @author tkyjovsk
|
||||
*/
|
||||
//@AdapterLibsLocationProperty("adapter.libs.eap")
|
||||
public class RelativeWildflyOIDCSessionAdapterTest extends AbstractSessionServletAdapterTest {
|
||||
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import org.keycloak.testsuite.adapter.servlet.AbstractSAMLServletsAdapterTest;
|
|||
/**
|
||||
* @author mhajas
|
||||
*/
|
||||
//@AdapterLibsLocationProperty("adapter.libs.eap")
|
||||
public class RelativeWildflySAMLAdapterTest extends AbstractSAMLServletsAdapterTest {
|
||||
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ package org.keycloak.testsuite.adapter.example;
|
|||
*
|
||||
* @author tkyjovsk
|
||||
*/
|
||||
//@AdapterLibsLocationProperty("adapter.libs.eap")
|
||||
public class RelativeWildflyBasicAuthExampleAdapterTest extends AbstractBasicAuthExampleAdapterTest {
|
||||
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ package org.keycloak.testsuite.adapter.example;
|
|||
*
|
||||
* @author fkiss
|
||||
*/
|
||||
//@AdapterLibsLocationProperty("adapter.libs.eap")
|
||||
public class RelativeWildflyCorsExampleAdapterTest extends AbstractCorsExampleAdapterTest {
|
||||
|
||||
}
|
|
@ -4,7 +4,6 @@ package org.keycloak.testsuite.adapter.example;
|
|||
*
|
||||
* @author tkyjovsk
|
||||
*/
|
||||
//@AdapterLibsLocationProperty("adapter.libs.eap")
|
||||
public class RelativeWildflyDemoExampleAdapterTest extends AbstractDemoExampleAdapterTest {
|
||||
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ package org.keycloak.testsuite.adapter.example;
|
|||
*
|
||||
* @author tkyjovsk
|
||||
*/
|
||||
//@AdapterLibsLocationProperty("adapter.libs.eap")
|
||||
public class RelativeWildflyJSConsoleExampleAdapterTest extends AbstractJSConsoleExampleAdapterTest {
|
||||
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ package org.keycloak.testsuite.adapter.example;
|
|||
*
|
||||
* @author mhajas
|
||||
*/
|
||||
//@AdapterLibsLocationProperty("adapter.libs.eap")
|
||||
public class RelativeWildflySAMLExampleAdapterTest extends AbstractSAMLExampleAdapterTest {
|
||||
|
||||
}
|
|
@ -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 {
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
}
|
|
@ -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 {
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
}
|
|
@ -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
Loading…
Reference in a new issue