Compare commits
281
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5870322259 | ||
|
|
bc298ca9f2 | ||
|
|
7ea1efb8b4 | ||
|
|
6c4448036c | ||
|
|
ff1e3928ac | ||
|
|
b5ce4db1c9 | ||
|
|
ea186b51c9 | ||
|
|
790c9c320a | ||
|
|
d31aa27b0f | ||
|
|
61a538ba29 | ||
|
|
9ae8d6aee1 | ||
|
|
98852e2f3f | ||
|
|
d997e73f2d | ||
|
|
fd08a884ad | ||
|
|
6c02510b92 | ||
|
|
7408600f94 | ||
|
|
229391d48b | ||
|
|
187fbfaf03 | ||
|
|
28547b0620 | ||
|
|
380f5dfb4e | ||
|
|
9c7e297118 | ||
|
|
ce94b7e9de | ||
|
|
f209476a1b | ||
|
|
bd08643f6c | ||
|
|
a9770073b2 | ||
|
|
da5332608c | ||
|
|
c43040a08e | ||
|
|
488351e46f | ||
|
|
bb2de4dc59 | ||
|
|
fe27f5364a | ||
|
|
82af7cbfa2 | ||
|
|
44d4f6eb95 | ||
|
|
8d1548bd4d | ||
|
|
9b0d5acb50 | ||
|
|
39686d5d4e | ||
|
|
78a1df693c | ||
|
|
8adad9dddf | ||
|
|
65362be4dd | ||
|
|
a6ca925340 | ||
|
|
97907cd7ff | ||
|
|
3d11a4746c | ||
|
|
0f25280611 | ||
|
|
99016cdc83 | ||
|
|
8e764e642f | ||
|
|
a56cef47f2 | ||
|
|
cf747dac22 | ||
|
|
0234bdb619 | ||
|
|
b88b520bad | ||
|
|
5446bf77e8 | ||
|
|
c5b72464cb | ||
|
|
917eb112ff | ||
|
|
0183ac43bc | ||
|
|
c660be7bbb | ||
|
|
935045926e | ||
|
|
d289fa7402 | ||
|
|
5831cffc19 | ||
|
|
03b8aa1fc2 | ||
|
|
05b6dc7af4 | ||
|
|
8c2d4812b0 | ||
|
|
fb5482a725 | ||
|
|
e43dd0ad19 | ||
|
|
0e6b25fa8d | ||
|
|
6f147f890d | ||
|
|
22ddf8b9d1 | ||
|
|
3b23101365 | ||
|
|
5e8ca5a140 | ||
|
|
da27f43573 | ||
|
|
c697945d39 | ||
|
|
fcda005d88 | ||
|
|
ca96c071e8 | ||
|
|
b23bf58170 | ||
|
|
27d217c220 | ||
|
|
6e4785e74c | ||
|
|
4eb60a169b | ||
|
|
eaaaf91963 | ||
|
|
12e2a4698d | ||
|
|
e5934e9d54 | ||
|
|
802e184ca9 | ||
|
|
cb110d095f | ||
|
|
e3609cc85b | ||
|
|
e2fd4d3b90 | ||
|
|
b1cfedb488 | ||
|
|
c6fc44bcc2 | ||
|
|
4b87b8f7e3 | ||
|
|
a538e25b9d | ||
|
|
971f0f5c16 | ||
|
|
1be070e34d | ||
|
|
dba7864180 | ||
|
|
ce76270ad8 | ||
|
|
a2e38d8bd4 | ||
|
|
319578f390 | ||
|
|
1e68f63715 | ||
|
|
d9331998c3 | ||
|
|
ad7e2cd12e | ||
|
|
3b30b63bcc | ||
|
|
4417f28c5a | ||
|
|
5fa5379f81 | ||
|
|
f715a026ba | ||
|
|
de29b566fe | ||
|
|
b3fe650e27 | ||
|
|
f38c6d3412 | ||
|
|
ed3d13d398 | ||
|
|
5bfb0e73ac | ||
|
|
3bfa79e210 | ||
|
|
4d3299ae08 | ||
|
|
8ec2b2398c | ||
|
|
f3da9760a3 | ||
|
|
87d4cc59a4 | ||
|
|
a36e43bacc | ||
|
|
668497df4d | ||
|
|
d3375962ad | ||
|
|
b155382523 | ||
|
|
e0730e5517 | ||
|
|
c1694a2791 | ||
|
|
dec82ddf68 | ||
|
|
00834ce3c1 | ||
|
|
2c218c9aa0 | ||
|
|
01c705b4d3 | ||
|
|
9565a785b2 | ||
|
|
dd4b2f811b | ||
|
|
ea6d7e1fac | ||
|
|
6b2a4229e3 | ||
|
|
63b41e2548 | ||
|
|
ed895ce02d | ||
|
|
61b71082f7 | ||
|
|
5478f282dc | ||
|
|
ebaa5bebe5 | ||
|
|
e2de6edff8 | ||
|
|
1d324d6b9a | ||
|
|
b0ce226005 | ||
|
|
a2be747f45 | ||
|
|
f8e68dadb5 | ||
|
|
8b05e2ebf8 | ||
|
|
d0ce72167d | ||
|
|
c91ecc3033 | ||
|
|
4ae6190b79 | ||
|
|
d87a26818e | ||
|
|
0dae2240e5 | ||
|
|
7d8f265789 | ||
|
|
8545457f5a | ||
|
|
ca2223abb8 | ||
|
|
01507fc1dc | ||
|
|
b9389100cd | ||
|
|
91c545534e | ||
|
|
3e5afcde9e | ||
|
|
c90bf2d9e1 | ||
|
|
638ce06f77 | ||
|
|
4750b22b6d | ||
|
|
7d59117fc1 | ||
|
|
425b2199f2 | ||
|
|
a882f95749 | ||
|
|
cdcbafa311 | ||
|
|
a36fd419b5 | ||
|
|
9029ec4f28 | ||
|
|
d013e9869a | ||
|
|
fe5eb1a06d | ||
|
|
582ee8897e | ||
|
|
4e41041469 | ||
|
|
8fbc8fc736 | ||
|
|
7760887ac1 | ||
|
|
7e7ab86821 | ||
|
|
106a0cb48d | ||
|
|
75be776aa1 | ||
|
|
2dbebd164f | ||
|
|
1021e8af5c | ||
|
|
2ad688a663 | ||
|
|
bf7effc6f2 | ||
|
|
d86547620a | ||
|
|
94de88ef3b | ||
|
|
101c7697fd | ||
|
|
cf94f4f84a | ||
|
|
6855b2f0e4 | ||
|
|
4d401224de | ||
|
|
4d007c776a | ||
|
|
eac1fb23cf | ||
|
|
d9ff44b870 | ||
|
|
deffa9b4e1 | ||
|
|
3d7fca885e | ||
|
|
08c5fed1b3 | ||
|
|
23d0361168 | ||
|
|
0ace5cd746 | ||
|
|
94da99bf10 | ||
|
|
3d5d7777f6 | ||
|
|
9954d68a1f | ||
|
|
00716b7bfc | ||
|
|
6d1555262e | ||
|
|
c00c712c39 | ||
|
|
63f4a32f2e | ||
|
|
2445575a04 | ||
|
|
56fe821bef | ||
|
|
36cc298b32 | ||
|
|
a00d36eea2 | ||
|
|
ac8b43358d | ||
|
|
1e33931f23 | ||
|
|
7e7406ddb7 | ||
|
|
84e1ace539 | ||
|
|
a1d1877751 | ||
|
|
390ca0930b | ||
|
|
13a2108846 | ||
|
|
9ffd517b53 | ||
|
|
5f1e6f3a23 | ||
|
|
6d5ab0f66b | ||
|
|
bc85be23b7 | ||
|
|
6522455b44 | ||
|
|
2e76be45fa | ||
|
|
0c3a9be1a1 | ||
|
|
a6bbc492b8 | ||
|
|
3d4ef91bf1 | ||
|
|
1604315e40 | ||
|
|
f702d8f1ff | ||
|
|
87f826c850 | ||
|
|
59bf7e524f | ||
|
|
e01424b815 | ||
|
|
c609ae3496 | ||
|
|
e3a3933390 | ||
|
|
1f40ab407c | ||
|
|
1d66bd9c15 | ||
|
|
777999e0ea | ||
|
|
0d5be568f8 | ||
|
|
17bb42d60e | ||
|
|
d6f030a05a | ||
|
|
18401815af | ||
|
|
10e618dee9 | ||
|
|
98f9c798f0 | ||
|
|
49f3172163 | ||
|
|
53489cd556 | ||
|
|
a5aa1da841 | ||
|
|
e11180a4f0 | ||
|
|
e6121f301f | ||
|
|
4050cf9ac3 | ||
|
|
50f148cd7c | ||
|
|
72b5632cfe | ||
|
|
8855bcf3c1 | ||
|
|
a85b58dccd | ||
|
|
01e6d09d79 | ||
|
|
597ee2b8c9 | ||
|
|
6ff37cfc24 | ||
|
|
95521e8a95 | ||
|
|
4b254475da | ||
|
|
6cf62a2768 | ||
|
|
71216bf2c9 | ||
|
|
cbc383d494 | ||
|
|
a75c9ee04e | ||
|
|
d7bcd41909 | ||
|
|
546d45b009 | ||
|
|
99738ea4ad | ||
|
|
4b399fe05a | ||
|
|
eb920b4993 | ||
|
|
1b6b95bb9a | ||
|
|
bd077a3adb | ||
|
|
fd0a000823 | ||
|
|
a6ae8d08ac | ||
|
|
e32f73880f | ||
|
|
63b65c933b | ||
|
|
72ec9ccb00 | ||
|
|
89dc55a106 | ||
|
|
80a9a8984a | ||
|
|
18fe808ce0 | ||
|
|
337b03fc62 | ||
|
|
617c61034f | ||
|
|
f026772c87 | ||
|
|
0f307afd16 | ||
|
|
a1f223735c | ||
|
|
d1bb872aec | ||
|
|
1d4e842cc0 | ||
|
|
209fdc1255 | ||
|
|
3ded1943e2 | ||
|
|
bdeb59f87e | ||
|
|
994adaf493 | ||
|
|
99c73a9cc7 | ||
|
|
6075ef221f | ||
|
|
fc867e59ea | ||
|
|
6212403569 | ||
|
|
75a3093dda | ||
|
|
6c46af5b3c | ||
|
|
67f10bee24 | ||
|
|
524b423733 | ||
|
|
0bf6c36ca7 | ||
|
|
66d58476d0 | ||
|
|
bf42227224 | ||
|
|
99a6713e6f |
No files matched your search
@@ -9,6 +9,11 @@
|
||||
.settings
|
||||
.classpath
|
||||
|
||||
|
||||
# NetBeans #
|
||||
############
|
||||
nb-configuration.xml
|
||||
|
||||
# Compiled source #
|
||||
###################
|
||||
*.com
|
||||
|
||||
@@ -5,7 +5,7 @@ Please visit [http://keycloak.org](http://keycloak.org) for more information on
|
||||
and video tutorials.
|
||||
|
||||
Keycloak is an SSO Service for web apps and REST services.
|
||||
It can be used for social applications as well as enterprise applications. It is based on OpenID Connect with SAML support in the works.
|
||||
It can be used for social applications as well as enterprise applications. It is based on OpenID Connect with support for SAML 2.0 as well.
|
||||
Here's some of the features:
|
||||
|
||||
* SSO and Single Log Out for browser applications
|
||||
@@ -30,6 +30,7 @@ Here's some of the features:
|
||||
* Revocation policies
|
||||
* Password policies
|
||||
* OpenID Connect Support
|
||||
* SAML Support
|
||||
|
||||
Please visit [http://keycloak.org](http://keycloak.org) for more information on Keycloak including how to download, documentation,
|
||||
and video tutorials.
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.1.0.Beta1</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>keycloak-connections-infinispan</artifactId>
|
||||
<name>Keycloak Connections Infinispan</name>
|
||||
<description/>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-model-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-core</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package org.keycloak.connections.infinispan;
|
||||
|
||||
import org.infinispan.Cache;
|
||||
import org.infinispan.manager.EmbeddedCacheManager;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class DefaultInfinispanConnectionProvider implements InfinispanConnectionProvider {
|
||||
|
||||
private EmbeddedCacheManager cacheManager;
|
||||
|
||||
public DefaultInfinispanConnectionProvider(EmbeddedCacheManager cacheManager) {
|
||||
this.cacheManager = cacheManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Cache<K, V> getCache(String name) {
|
||||
return cacheManager.getCache(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
|
||||
}
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
package org.keycloak.connections.infinispan;
|
||||
|
||||
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.manager.DefaultCacheManager;
|
||||
import org.infinispan.manager.EmbeddedCacheManager;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.Config;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
|
||||
import javax.naming.InitialContext;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class DefaultInfinispanConnectionProviderFactory implements InfinispanConnectionProviderFactory {
|
||||
|
||||
protected static final Logger logger = Logger.getLogger(DefaultInfinispanConnectionProviderFactory.class);
|
||||
|
||||
private Config.Scope config;
|
||||
|
||||
private EmbeddedCacheManager cacheManager;
|
||||
|
||||
private boolean containerManaged;
|
||||
|
||||
@Override
|
||||
public InfinispanConnectionProvider create(KeycloakSession session) {
|
||||
lazyInit();
|
||||
|
||||
return new DefaultInfinispanConnectionProvider(cacheManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if (cacheManager != null && !containerManaged) {
|
||||
cacheManager.stop();
|
||||
}
|
||||
cacheManager = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "default";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Config.Scope config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
private void lazyInit() {
|
||||
if (cacheManager == null) {
|
||||
synchronized (this) {
|
||||
if (cacheManager == null) {
|
||||
String cacheContainer = config.get("cacheContainer");
|
||||
if (cacheContainer != null) {
|
||||
initContainerManaged(cacheContainer);
|
||||
} else {
|
||||
initEmbedded();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initContainerManaged(String cacheContainerLookup) {
|
||||
try {
|
||||
cacheManager = (EmbeddedCacheManager) new InitialContext().lookup(cacheContainerLookup);
|
||||
containerManaged = true;
|
||||
|
||||
logger.debugv("Using container managed Infinispan cache container, lookup={1}", cacheContainerLookup);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to retrieve cache container", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void initEmbedded() {
|
||||
GlobalConfigurationBuilder gcb = new GlobalConfigurationBuilder();
|
||||
|
||||
boolean clustered = config.getBoolean("clustered", false);
|
||||
boolean async = config.getBoolean("async", true);
|
||||
|
||||
if (clustered) {
|
||||
gcb.transport().defaultTransport();
|
||||
}
|
||||
cacheManager = new DefaultCacheManager(gcb.build());
|
||||
containerManaged = false;
|
||||
|
||||
logger.debug("Started embedded Infinispan cache container");
|
||||
|
||||
ConfigurationBuilder invalidationConfigBuilder = new ConfigurationBuilder();
|
||||
if (clustered) {
|
||||
invalidationConfigBuilder.clustering().cacheMode(async ? CacheMode.INVALIDATION_ASYNC : CacheMode.INVALIDATION_SYNC);
|
||||
}
|
||||
Configuration invalidationCacheConfiguration = invalidationConfigBuilder.build();
|
||||
|
||||
cacheManager.defineConfiguration(InfinispanConnectionProvider.REALM_CACHE_NAME, invalidationCacheConfiguration);
|
||||
cacheManager.defineConfiguration(InfinispanConnectionProvider.USER_CACHE_NAME, invalidationCacheConfiguration);
|
||||
|
||||
ConfigurationBuilder sessionConfigBuilder = new ConfigurationBuilder();
|
||||
if (clustered) {
|
||||
String sessionsMode = config.get("sessionsMode", "distributed");
|
||||
if (sessionsMode.equalsIgnoreCase("replicated")) {
|
||||
sessionConfigBuilder.clustering().cacheMode(async ? CacheMode.REPL_ASYNC : CacheMode.REPL_SYNC);
|
||||
} else if (sessionsMode.equalsIgnoreCase("distributed")) {
|
||||
sessionConfigBuilder.clustering().cacheMode(async ? CacheMode.DIST_ASYNC : CacheMode.DIST_SYNC);
|
||||
} else {
|
||||
throw new RuntimeException("Invalid value for sessionsMode");
|
||||
}
|
||||
|
||||
sessionConfigBuilder.clustering().hash()
|
||||
.numOwners(config.getInt("sessionsOwners", 2))
|
||||
.numSegments(config.getInt("sessionsSegments", 60)).build();
|
||||
}
|
||||
|
||||
Configuration sessionCacheConfiguration = sessionConfigBuilder.build();
|
||||
cacheManager.defineConfiguration(InfinispanConnectionProvider.SESSION_CACHE_NAME, sessionCacheConfiguration);
|
||||
cacheManager.defineConfiguration(InfinispanConnectionProvider.LOGIN_FAILURE_CACHE_NAME, sessionCacheConfiguration);
|
||||
}
|
||||
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package org.keycloak.connections.infinispan;
|
||||
|
||||
import org.infinispan.Cache;
|
||||
import org.keycloak.provider.Provider;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public interface InfinispanConnectionProvider extends Provider {
|
||||
|
||||
static final String REALM_CACHE_NAME = "realms";
|
||||
static final String USER_CACHE_NAME = "users";
|
||||
static final String SESSION_CACHE_NAME = "sessions";
|
||||
static final String LOGIN_FAILURE_CACHE_NAME = "loginFailures";
|
||||
|
||||
<K, V> Cache<K, V> getCache(String name);
|
||||
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package org.keycloak.connections.infinispan;
|
||||
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public interface InfinispanConnectionProviderFactory extends ProviderFactory<InfinispanConnectionProvider> {
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package org.keycloak.connections.infinispan;
|
||||
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.provider.Spi;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class InfinispanConnectionSpi implements Spi {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "connectionsInfinispan";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Provider> getProviderClass() {
|
||||
return InfinispanConnectionProvider.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends ProviderFactory> getProviderFactoryClass() {
|
||||
return InfinispanConnectionProviderFactory.class;
|
||||
}
|
||||
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
org.keycloak.connections.infinispan.DefaultInfinispanConnectionProviderFactory
|
||||
@@ -0,0 +1 @@
|
||||
org.keycloak.connections.infinispan.InfinispanConnectionSpi
|
||||
Executable
+72
@@ -0,0 +1,72 @@
|
||||
<?xml version="1.0"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.1.0.Beta1</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>keycloak-connections-jpa-liquibase</artifactId>
|
||||
<name>Keycloak Connections JPA Liquibase Updater</name>
|
||||
<description/>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-connections-jpa</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.liquibase</groupId>
|
||||
<artifactId>liquibase-core</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.logging</groupId>
|
||||
<artifactId>jboss-logging</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.liquibase</groupId>
|
||||
<artifactId>liquibase-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<changeLogFile>META-INF/jpa-changelog-master.xml</changeLogFile>
|
||||
|
||||
<url>${url}</url>
|
||||
<driver>${driver}</driver>
|
||||
<username>${username}</username>
|
||||
<password>${password}</password>
|
||||
|
||||
<referenceUrl>${referenceUrl}</referenceUrl>
|
||||
<referenceDriver>${driver}</referenceDriver>
|
||||
<referenceUsername>${username}</referenceUsername>
|
||||
<referencePassword>${password}</referencePassword>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>${h2.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<username>sa</username>
|
||||
<password></password>
|
||||
<driver>org.h2.Driver</driver>
|
||||
</properties>
|
||||
</project>
|
||||
+224
@@ -0,0 +1,224 @@
|
||||
package org.keycloak.connections.jpa.updater.liquibase;
|
||||
|
||||
import liquibase.Contexts;
|
||||
import liquibase.Liquibase;
|
||||
import liquibase.changelog.ChangeSet;
|
||||
import liquibase.changelog.DatabaseChangeLog;
|
||||
import liquibase.changelog.RanChangeSet;
|
||||
import liquibase.database.Database;
|
||||
import liquibase.database.DatabaseFactory;
|
||||
import liquibase.database.core.DB2Database;
|
||||
import liquibase.database.core.DerbyDatabase;
|
||||
import liquibase.database.core.FirebirdDatabase;
|
||||
import liquibase.database.core.H2Database;
|
||||
import liquibase.database.core.HsqlDatabase;
|
||||
import liquibase.database.core.InformixDatabase;
|
||||
import liquibase.database.core.MSSQLDatabase;
|
||||
import liquibase.database.core.MySQLDatabase;
|
||||
import liquibase.database.core.OracleDatabase;
|
||||
import liquibase.database.core.PostgresDatabase;
|
||||
import liquibase.database.core.SQLiteDatabase;
|
||||
import liquibase.database.core.SybaseASADatabase;
|
||||
import liquibase.database.core.SybaseDatabase;
|
||||
import liquibase.database.jvm.JdbcConnection;
|
||||
import liquibase.exception.LiquibaseException;
|
||||
import liquibase.logging.LogFactory;
|
||||
import liquibase.logging.LogLevel;
|
||||
import liquibase.resource.ClassLoaderResourceAccessor;
|
||||
import liquibase.servicelocator.ServiceLocator;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.connections.jpa.updater.JpaUpdaterProvider;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class LiquibaseJpaUpdaterProvider implements JpaUpdaterProvider {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(LiquibaseJpaUpdaterProvider.class);
|
||||
|
||||
private static final String CHANGELOG = "META-INF/jpa-changelog-master.xml";
|
||||
|
||||
@Override
|
||||
public String getCurrentVersionSql() {
|
||||
return "SELECT ID from DATABASECHANGELOG ORDER BY DATEEXECUTED DESC LIMIT 1";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Connection connection) {
|
||||
logger.debug("Starting database update");
|
||||
|
||||
try {
|
||||
Liquibase liquibase = getLiquibase(connection);
|
||||
|
||||
List<ChangeSet> changeSets = liquibase.listUnrunChangeSets((Contexts) null);
|
||||
if (!changeSets.isEmpty()) {
|
||||
if (changeSets.get(0).getId().equals(FIRST_VERSION)) {
|
||||
Statement statement = connection.createStatement();
|
||||
try {
|
||||
statement.executeQuery("SELECT id FROM REALM");
|
||||
|
||||
logger.infov("Updating database from {0} to {1}", FIRST_VERSION, changeSets.get(changeSets.size() - 1).getId());
|
||||
liquibase.markNextChangeSetRan((Contexts) null);
|
||||
} catch (SQLException e) {
|
||||
logger.info("Initializing database schema");
|
||||
}
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
List<RanChangeSet> ranChangeSets = liquibase.getDatabase().getRanChangeSetList();
|
||||
logger.debugv("Updating database from {0} to {1}", ranChangeSets.get(ranChangeSets.size() - 1).getId(), changeSets.get(changeSets.size() - 1).getId());
|
||||
} else {
|
||||
logger.infov("Updating database");
|
||||
}
|
||||
}
|
||||
|
||||
liquibase.update((Contexts) null);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to update database", e);
|
||||
}
|
||||
logger.debug("Completed database update");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate(Connection connection) {
|
||||
try {
|
||||
Liquibase liquibase = getLiquibase(connection);
|
||||
|
||||
liquibase.validate();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to validate database", e);
|
||||
}
|
||||
}
|
||||
|
||||
private Liquibase getLiquibase(Connection connection) throws Exception {
|
||||
ServiceLocator sl = ServiceLocator.getInstance();
|
||||
|
||||
if (!System.getProperties().containsKey("liquibase.scan.packages")) {
|
||||
if (sl.getPackages().remove("liquibase.core")) {
|
||||
sl.addPackageToScan("liquibase.core.xml");
|
||||
}
|
||||
|
||||
if (sl.getPackages().remove("liquibase.parser")) {
|
||||
sl.addPackageToScan("liquibase.parser.core.xml");
|
||||
}
|
||||
|
||||
if (sl.getPackages().remove("liquibase.serializer")) {
|
||||
sl.addPackageToScan("liquibase.serializer.core.xml");
|
||||
}
|
||||
|
||||
sl.getPackages().remove("liquibase.ext");
|
||||
sl.getPackages().remove("liquibase.sdk");
|
||||
}
|
||||
|
||||
LogFactory.setInstance(new LogWrapper());
|
||||
Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(connection));
|
||||
return new Liquibase(CHANGELOG, new ClassLoaderResourceAccessor(getClass().getClassLoader()), database);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
|
||||
private static class LogWrapper extends LogFactory {
|
||||
|
||||
private liquibase.logging.Logger logger = new liquibase.logging.Logger() {
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLogLevel(String level) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLogLevel(LogLevel level) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLogLevel(String logLevel, String logFile) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void severe(String message) {
|
||||
LiquibaseJpaUpdaterProvider.logger.error(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void severe(String message, Throwable e) {
|
||||
LiquibaseJpaUpdaterProvider.logger.error(message, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warning(String message) {
|
||||
LiquibaseJpaUpdaterProvider.logger.warn(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warning(String message, Throwable e) {
|
||||
LiquibaseJpaUpdaterProvider.logger.warn(message, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(String message) {
|
||||
LiquibaseJpaUpdaterProvider.logger.debug(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(String message, Throwable e) {
|
||||
LiquibaseJpaUpdaterProvider.logger.debug(message, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(String message) {
|
||||
LiquibaseJpaUpdaterProvider.logger.trace(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LogLevel getLogLevel() {
|
||||
if (LiquibaseJpaUpdaterProvider.logger.isTraceEnabled()) {
|
||||
return LogLevel.DEBUG;
|
||||
} else if (LiquibaseJpaUpdaterProvider.logger.isDebugEnabled()) {
|
||||
return LogLevel.INFO;
|
||||
} else {
|
||||
return LogLevel.WARNING;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(String message, Throwable e) {
|
||||
LiquibaseJpaUpdaterProvider.logger.trace(message, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChangeLog(DatabaseChangeLog databaseChangeLog) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChangeSet(ChangeSet changeSet) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public liquibase.logging.Logger getLog(String name) {
|
||||
return logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public liquibase.logging.Logger getLog() {
|
||||
return logger;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package org.keycloak.connections.jpa.updater.liquibase;
|
||||
|
||||
import org.keycloak.Config;
|
||||
import org.keycloak.connections.jpa.updater.JpaUpdaterProvider;
|
||||
import org.keycloak.connections.jpa.updater.JpaUpdaterProviderFactory;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class LiquibaseJpaUpdaterProviderFactory implements JpaUpdaterProviderFactory {
|
||||
|
||||
@Override
|
||||
public JpaUpdaterProvider create(KeycloakSession session) {
|
||||
return new LiquibaseJpaUpdaterProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Config.Scope config) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "liquibase";
|
||||
}
|
||||
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
package org.keycloak.connections.jpa.updater.liquibase.custom;
|
||||
|
||||
import liquibase.change.custom.CustomSqlChange;
|
||||
import liquibase.database.Database;
|
||||
import liquibase.database.jvm.JdbcConnection;
|
||||
import liquibase.exception.CustomChangeException;
|
||||
import liquibase.exception.SetupException;
|
||||
import liquibase.exception.ValidationErrors;
|
||||
import liquibase.resource.ResourceAccessor;
|
||||
import liquibase.statement.SqlStatement;
|
||||
import liquibase.statement.core.UpdateStatement;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class AddRealmCodeSecret implements CustomSqlChange {
|
||||
|
||||
private String confirmationMessage;
|
||||
|
||||
@Override
|
||||
public SqlStatement[] generateStatements(Database database) throws CustomChangeException {
|
||||
try {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Generated codeSecret for realms: ");
|
||||
|
||||
Connection connection = ((JdbcConnection) (database.getConnection())).getWrappedConnection();
|
||||
ResultSet resultSet = connection.createStatement().executeQuery("SELECT ID FROM REALM WHERE CODE_SECRET IS NULL");
|
||||
|
||||
ArrayList<SqlStatement> statements = new ArrayList<SqlStatement>();
|
||||
while (resultSet.next()) {
|
||||
String id = resultSet.getString(1);
|
||||
|
||||
UpdateStatement statement = new UpdateStatement(null, null, "REALM")
|
||||
.addNewColumnValue("CODE_SECRET", KeycloakModelUtils.generateCodeSecret())
|
||||
.setWhereClause("ID='" + id + "'");
|
||||
statements.add(statement);
|
||||
|
||||
if (!resultSet.isFirst()) {
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append(id);
|
||||
}
|
||||
|
||||
if (!statements.isEmpty()) {
|
||||
confirmationMessage = sb.toString();
|
||||
}
|
||||
|
||||
return statements.toArray(new SqlStatement[statements.size()]);
|
||||
} catch (Exception e) {
|
||||
throw new CustomChangeException("Failed to add realm code secret", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConfirmationMessage() {
|
||||
return confirmationMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUp() throws SetupException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFileOpener(ResourceAccessor resourceAccessor) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValidationErrors validate(Database database) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,420 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.2.xsd">
|
||||
<changeSet author="sthorger@redhat.com" id="1.0.0.Final">
|
||||
<createTable tableName="APPLICATION_DEFAULT_ROLES">
|
||||
<column name="APPLICATION_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="ROLE_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<createTable tableName="CLIENT">
|
||||
<column name="DTYPE" type="VARCHAR(31)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="ALLOWED_CLAIMS_MASK" type="BIGINT"/>
|
||||
<column name="ENABLED" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="FULL_SCOPE_ALLOWED" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="NAME" type="VARCHAR(255)"/>
|
||||
<column name="NOT_BEFORE" type="INT"/>
|
||||
<column name="PUBLIC_CLIENT" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="SECRET" type="VARCHAR(255)"/>
|
||||
<column name="BASE_URL" type="VARCHAR(255)"/>
|
||||
<column name="BEARER_ONLY" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="MANAGEMENT_URL" type="VARCHAR(255)"/>
|
||||
<column name="SURROGATE_AUTH_REQUIRED" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="DIRECT_GRANTS_ONLY" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="REALM_ID" type="VARCHAR(36)"/>
|
||||
</createTable>
|
||||
<createTable tableName="CLIENT_SESSION">
|
||||
<column name="ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="ACTION" type="INT"/>
|
||||
<column name="CLIENT_ID" type="VARCHAR(36)"/>
|
||||
<column name="REDIRECT_URI" type="VARCHAR(255)"/>
|
||||
<column name="STATE" type="VARCHAR(255)"/>
|
||||
<column name="TIMESTAMP" type="INT"/>
|
||||
<column name="SESSION_ID" type="VARCHAR(36)"/>
|
||||
</createTable>
|
||||
<createTable tableName="CLIENT_SESSION_ROLE">
|
||||
<column name="ROLE_ID" type="VARCHAR(255)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="CLIENT_SESSION" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<createTable tableName="COMPOSITE_ROLE">
|
||||
<column name="COMPOSITE" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="CHILD_ROLE" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<createTable tableName="CREDENTIAL">
|
||||
<column name="ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="DEVICE" type="VARCHAR(255)"/>
|
||||
<column name="HASH_ITERATIONS" type="INT"/>
|
||||
<column name="SALT" type="BLOB(16)"/>
|
||||
<column name="TYPE" type="VARCHAR(255)"/>
|
||||
<column name="VALUE" type="VARCHAR(255)"/>
|
||||
<column name="USER_ID" type="VARCHAR(36)"/>
|
||||
</createTable>
|
||||
<createTable tableName="EVENT_ENTITY">
|
||||
<column name="ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="CLIENT_ID" type="VARCHAR(255)"/>
|
||||
<column name="DETAILS_JSON" type="VARCHAR(2550)"/>
|
||||
<column name="ERROR" type="VARCHAR(255)"/>
|
||||
<column name="IP_ADDRESS" type="VARCHAR(255)"/>
|
||||
<column name="REALM_ID" type="VARCHAR(255)"/>
|
||||
<column name="SESSION_ID" type="VARCHAR(255)"/>
|
||||
<column name="TIME" type="BIGINT"/>
|
||||
<column name="TYPE" type="VARCHAR(255)"/>
|
||||
<column name="USER_ID" type="VARCHAR(255)"/>
|
||||
</createTable>
|
||||
<createTable tableName="FED_PROVIDERS">
|
||||
<column name="REALM_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="USERFEDERATIONPROVIDERS_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<createTable tableName="KEYCLOAK_ROLE">
|
||||
<column name="ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="APP_REALM_CONSTRAINT" type="VARCHAR(36)"/>
|
||||
<column name="APPLICATION_ROLE" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="DESCRIPTION" type="VARCHAR(255)"/>
|
||||
<column name="NAME" type="VARCHAR(255)"/>
|
||||
<column name="REALM_ID" type="VARCHAR(255)"/>
|
||||
<column name="APPLICATION" type="VARCHAR(36)"/>
|
||||
<column name="REALM" type="VARCHAR(36)"/>
|
||||
</createTable>
|
||||
<createTable tableName="REALM">
|
||||
<column name="ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="ACCESS_CODE_LIFESPAN" type="INT"/>
|
||||
<column name="USER_ACTION_LIFESPAN" type="INT"/>
|
||||
<column name="ACCESS_TOKEN_LIFESPAN" type="INT"/>
|
||||
<column name="ACCOUNT_THEME" type="VARCHAR(255)"/>
|
||||
<column name="ADMIN_THEME" type="VARCHAR(255)"/>
|
||||
<column name="EMAIL_THEME" type="VARCHAR(255)"/>
|
||||
<column name="ENABLED" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="EVENTS_ENABLED" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="EVENTS_EXPIRATION" type="BIGINT"/>
|
||||
<column name="LOGIN_THEME" type="VARCHAR(255)"/>
|
||||
<column name="NAME" type="VARCHAR(255)"/>
|
||||
<column name="NOT_BEFORE" type="INT"/>
|
||||
<column name="PASSWORD_CRED_GRANT_ALLOWED" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="PASSWORD_POLICY" type="VARCHAR(255)"/>
|
||||
<column name="PRIVATE_KEY" type="VARCHAR(2048)"/>
|
||||
<column name="PUBLIC_KEY" type="VARCHAR(2048)"/>
|
||||
<column name="REGISTRATION_ALLOWED" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="REMEMBER_ME" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="RESET_PASSWORD_ALLOWED" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="SOCIAL" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="SSL_REQUIRED" type="VARCHAR(255)"/>
|
||||
<column name="SSO_IDLE_TIMEOUT" type="INT"/>
|
||||
<column name="SSO_MAX_LIFESPAN" type="INT"/>
|
||||
<column name="UPDATE_PROFILE_ON_SOC_LOGIN" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="VERIFY_EMAIL" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="MASTER_ADMIN_APP" type="VARCHAR(36)"/>
|
||||
</createTable>
|
||||
<createTable tableName="REALM_APPLICATION">
|
||||
<column name="APPLICATION_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="REALM_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<createTable tableName="REALM_ATTRIBUTE">
|
||||
<column name="NAME" type="VARCHAR(255)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="VALUE" type="VARCHAR(255)"/>
|
||||
<column name="REALM_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<createTable tableName="REALM_DEFAULT_ROLES">
|
||||
<column name="REALM_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="ROLE_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<createTable tableName="REALM_EVENTS_LISTENERS">
|
||||
<column name="REALM_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="VALUE" type="VARCHAR(255)"/>
|
||||
</createTable>
|
||||
<createTable tableName="REALM_REQUIRED_CREDENTIAL">
|
||||
<column name="TYPE" type="VARCHAR(255)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="FORM_LABEL" type="VARCHAR(255)"/>
|
||||
<column name="INPUT" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="SECRET" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="REALM_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<createTable tableName="REALM_SMTP_CONFIG">
|
||||
<column name="REALM_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="VALUE" type="VARCHAR(255)"/>
|
||||
<column name="NAME" type="VARCHAR(255)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<createTable tableName="REALM_SOCIAL_CONFIG">
|
||||
<column name="REALM_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="VALUE" type="VARCHAR(255)"/>
|
||||
<column name="NAME" type="VARCHAR(255)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<createTable tableName="REDIRECT_URIS">
|
||||
<column name="CLIENT_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="VALUE" type="VARCHAR(255)"/>
|
||||
</createTable>
|
||||
<createTable tableName="SCOPE_MAPPING">
|
||||
<column name="CLIENT_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="ROLE_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<createTable tableName="USERNAME_LOGIN_FAILURE">
|
||||
<column name="REALM_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="USERNAME" type="VARCHAR(200)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="FAILED_LOGIN_NOT_BEFORE" type="INT"/>
|
||||
<column name="LAST_FAILURE" type="BIGINT"/>
|
||||
<column name="LAST_IP_FAILURE" type="VARCHAR(255)"/>
|
||||
<column name="NUM_FAILURES" type="INT"/>
|
||||
</createTable>
|
||||
<createTable tableName="USER_ATTRIBUTE">
|
||||
<column name="NAME" type="VARCHAR(255)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="VALUE" type="VARCHAR(255)"/>
|
||||
<column name="USER_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<createTable tableName="USER_ENTITY">
|
||||
<column name="ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="EMAIL" type="VARCHAR(255)"/>
|
||||
<column name="EMAIL_CONSTRAINT" type="VARCHAR(255)"/>
|
||||
<column name="EMAIL_VERIFIED" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="ENABLED" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="FEDERATION_LINK" type="VARCHAR(255)"/>
|
||||
<column name="FIRST_NAME" type="VARCHAR(255)"/>
|
||||
<column name="LAST_NAME" type="VARCHAR(255)"/>
|
||||
<column name="REALM_ID" type="VARCHAR(255)"/>
|
||||
<column name="TOTP" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="USERNAME" type="VARCHAR(255)"/>
|
||||
</createTable>
|
||||
<createTable tableName="USER_FEDERATION_CONFIG">
|
||||
<column name="USER_FEDERATION_PROVIDER_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="VALUE" type="VARCHAR(255)"/>
|
||||
<column name="NAME" type="VARCHAR(255)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<createTable tableName="USER_FEDERATION_PROVIDER">
|
||||
<column name="ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="CHANGED_SYNC_PERIOD" type="INT"/>
|
||||
<column name="DISPLAY_NAME" type="VARCHAR(255)"/>
|
||||
<column name="FULL_SYNC_PERIOD" type="INT"/>
|
||||
<column name="LAST_SYNC" type="INT"/>
|
||||
<column name="PRIORITY" type="INT"/>
|
||||
<column name="PROVIDER_NAME" type="VARCHAR(255)"/>
|
||||
<column name="REALM_ID" type="VARCHAR(36)"/>
|
||||
</createTable>
|
||||
<createTable tableName="USER_REQUIRED_ACTION">
|
||||
<column name="ACTION" type="INT">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="USER_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<createTable tableName="USER_ROLE_MAPPING">
|
||||
<column name="ROLE_ID" type="VARCHAR(255)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="USER_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<createTable tableName="USER_SESSION">
|
||||
<column name="ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="AUTH_METHOD" type="VARCHAR(255)"/>
|
||||
<column name="IP_ADDRESS" type="VARCHAR(255)"/>
|
||||
<column name="LAST_SESSION_REFRESH" type="INT"/>
|
||||
<column name="LOGIN_USERNAME" type="VARCHAR(255)"/>
|
||||
<column name="REALM_ID" type="VARCHAR(255)"/>
|
||||
<column name="REMEMBER_ME" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="STARTED" type="INT"/>
|
||||
<column name="USER_ID" type="VARCHAR(255)"/>
|
||||
</createTable>
|
||||
<createTable tableName="USER_SOCIAL_LINK">
|
||||
<column name="SOCIAL_PROVIDER" type="VARCHAR(255)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="REALM_ID" type="VARCHAR(255)"/>
|
||||
<column name="SOCIAL_USER_ID" type="VARCHAR(255)"/>
|
||||
<column name="SOCIAL_USERNAME" type="VARCHAR(255)"/>
|
||||
<column name="USER_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<createTable tableName="WEB_ORIGINS">
|
||||
<column name="CLIENT_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="VALUE" type="VARCHAR(255)"/>
|
||||
</createTable>
|
||||
<addPrimaryKey columnNames="REALM_ID, NAME" constraintName="CONSTRAINT_1" tableName="REALM_SOCIAL_CONFIG"/>
|
||||
<addPrimaryKey columnNames="REALM_ID, USERNAME" constraintName="CONSTRAINT_17" tableName="USERNAME_LOGIN_FAILURE"/>
|
||||
<addPrimaryKey columnNames="ACTION, USER_ID" constraintName="CONSTRAINT_2" tableName="USER_REQUIRED_ACTION"/>
|
||||
<addPrimaryKey columnNames="SOCIAL_PROVIDER, USER_ID" constraintName="CONSTRAINT_3" tableName="USER_SOCIAL_LINK"/>
|
||||
<addPrimaryKey columnNames="ID" constraintName="CONSTRAINT_4" tableName="EVENT_ENTITY"/>
|
||||
<addPrimaryKey columnNames="ID" constraintName="CONSTRAINT_4A" tableName="REALM"/>
|
||||
<addPrimaryKey columnNames="CLIENT_SESSION, ROLE_ID" constraintName="CONSTRAINT_5" tableName="CLIENT_SESSION_ROLE"/>
|
||||
<addPrimaryKey columnNames="ID" constraintName="CONSTRAINT_57" tableName="USER_SESSION"/>
|
||||
<addPrimaryKey columnNames="ID" constraintName="CONSTRAINT_5C" tableName="USER_FEDERATION_PROVIDER"/>
|
||||
<addPrimaryKey columnNames="NAME, USER_ID" constraintName="CONSTRAINT_6" tableName="USER_ATTRIBUTE"/>
|
||||
<addPrimaryKey columnNames="ID" constraintName="CONSTRAINT_7" tableName="CLIENT"/>
|
||||
<addPrimaryKey columnNames="ID" constraintName="CONSTRAINT_8" tableName="CLIENT_SESSION"/>
|
||||
<addPrimaryKey columnNames="CLIENT_ID, ROLE_ID" constraintName="CONSTRAINT_81" tableName="SCOPE_MAPPING"/>
|
||||
<addPrimaryKey columnNames="NAME, REALM_ID" constraintName="CONSTRAINT_9" tableName="REALM_ATTRIBUTE"/>
|
||||
<addPrimaryKey columnNames="REALM_ID, TYPE" constraintName="CONSTRAINT_92" tableName="REALM_REQUIRED_CREDENTIAL"/>
|
||||
<addPrimaryKey columnNames="ID" constraintName="CONSTRAINT_A" tableName="KEYCLOAK_ROLE"/>
|
||||
<addPrimaryKey columnNames="ROLE_ID, USER_ID" constraintName="CONSTRAINT_C" tableName="USER_ROLE_MAPPING"/>
|
||||
<addPrimaryKey columnNames="REALM_ID, NAME" constraintName="CONSTRAINT_E" tableName="REALM_SMTP_CONFIG"/>
|
||||
<addPrimaryKey columnNames="ID" constraintName="CONSTRAINT_F" tableName="CREDENTIAL"/>
|
||||
<addPrimaryKey columnNames="USER_FEDERATION_PROVIDER_ID, NAME" constraintName="CONSTRAINT_F9" tableName="USER_FEDERATION_CONFIG"/>
|
||||
<addPrimaryKey columnNames="ID" constraintName="CONSTRAINT_FB" tableName="USER_ENTITY"/>
|
||||
<addUniqueConstraint columnNames="ROLE_ID" constraintName="UK_8AELWNIBJI49AVXSRTUF6XJOW" tableName="APPLICATION_DEFAULT_ROLES"/>
|
||||
<addUniqueConstraint columnNames="REALM_ID,NAME" constraintName="UK_B71CJLBENV945RB6GCON438AT" tableName="CLIENT"/>
|
||||
<addUniqueConstraint columnNames="USERFEDERATIONPROVIDERS_ID" constraintName="UK_DCCIRJLIPU1478VQC89DID88C" tableName="FED_PROVIDERS"/>
|
||||
<addUniqueConstraint columnNames="REALM_ID,EMAIL_CONSTRAINT" constraintName="UK_DYKN684SL8UP1CRFEI6ECKHD7" tableName="USER_ENTITY"/>
|
||||
<addUniqueConstraint columnNames="ROLE_ID" constraintName="UK_H4WPD7W4HSOOLNI3H0SW7BTJE" tableName="REALM_DEFAULT_ROLES"/>
|
||||
<addUniqueConstraint columnNames="NAME,APP_REALM_CONSTRAINT" constraintName="UK_J3RWUVD56ONTGSUHOGM184WW2" tableName="KEYCLOAK_ROLE"/>
|
||||
<addUniqueConstraint columnNames="REALM_ID" constraintName="UK_L5QGA3RFME47335JY8JXYXH3I" tableName="REALM_APPLICATION"/>
|
||||
<addUniqueConstraint columnNames="NAME" constraintName="UK_ORVSDMLA56612EAEFIQ6WL5OI" tableName="REALM"/>
|
||||
<addUniqueConstraint columnNames="REALM_ID,USERNAME" constraintName="UK_RU8TT6T700S9V50BU18WS5HA6" tableName="USER_ENTITY"/>
|
||||
<addForeignKeyConstraint baseColumnNames="CLIENT_SESSION" baseTableName="CLIENT_SESSION_ROLE" constraintName="FK_11B7SGQW18I532811V7O2DV76" referencedColumnNames="ID" referencedTableName="CLIENT_SESSION"/>
|
||||
<addForeignKeyConstraint baseColumnNames="CLIENT_ID" baseTableName="REDIRECT_URIS" constraintName="FK_1BURS8PB4OUJ97H5WUPPAHV9F" referencedColumnNames="ID" referencedTableName="CLIENT"/>
|
||||
<addForeignKeyConstraint baseColumnNames="REALM_ID" baseTableName="USER_FEDERATION_PROVIDER" constraintName="FK_1FJ32F6PTOLW2QY60CD8N01E8" referencedColumnNames="ID" referencedTableName="REALM"/>
|
||||
<addForeignKeyConstraint baseColumnNames="REALM_ID" baseTableName="FED_PROVIDERS" constraintName="FK_213LYQ09FKXQ8K8NY8DY3737T" referencedColumnNames="ID" referencedTableName="REALM"/>
|
||||
<addForeignKeyConstraint baseColumnNames="REALM_ID" baseTableName="REALM_REQUIRED_CREDENTIAL" constraintName="FK_5HG65LYBEVAVKQFKI3KPONH9V" referencedColumnNames="ID" referencedTableName="REALM"/>
|
||||
<addForeignKeyConstraint baseColumnNames="USER_ID" baseTableName="USER_ATTRIBUTE" constraintName="FK_5HRM2VLF9QL5FU043KQEPOVBR" referencedColumnNames="ID" referencedTableName="USER_ENTITY"/>
|
||||
<addForeignKeyConstraint baseColumnNames="USER_ID" baseTableName="USER_SOCIAL_LINK" constraintName="FK_68CJYS5UWM55UY823Y75XG4OM" referencedColumnNames="ID" referencedTableName="USER_ENTITY"/>
|
||||
<addForeignKeyConstraint baseColumnNames="USER_ID" baseTableName="USER_REQUIRED_ACTION" constraintName="FK_6QJ3W1JW9CVAFHE19BWSIUVMD" referencedColumnNames="ID" referencedTableName="USER_ENTITY"/>
|
||||
<addForeignKeyConstraint baseColumnNames="REALM" baseTableName="KEYCLOAK_ROLE" constraintName="FK_6VYQFE4CN4WLQ8R6KT5VDSJ5C" referencedColumnNames="ID" referencedTableName="REALM"/>
|
||||
<addForeignKeyConstraint baseColumnNames="REALM_ID" baseTableName="REALM_SMTP_CONFIG" constraintName="FK_70EJ8XDXGXD0B9HH6180IRR0O" referencedColumnNames="ID" referencedTableName="REALM"/>
|
||||
<addForeignKeyConstraint baseColumnNames="APPLICATION_ID" baseTableName="REALM_APPLICATION" constraintName="FK_71S3P0DIUXAWWQQSA528UBY2Q" referencedColumnNames="ID" referencedTableName="REALM"/>
|
||||
<addForeignKeyConstraint baseColumnNames="ROLE_ID" baseTableName="APPLICATION_DEFAULT_ROLES" constraintName="FK_8AELWNIBJI49AVXSRTUF6XJOW" referencedColumnNames="ID" referencedTableName="KEYCLOAK_ROLE"/>
|
||||
<addForeignKeyConstraint baseColumnNames="REALM_ID" baseTableName="REALM_ATTRIBUTE" constraintName="FK_8SHXD6L3E9ATQUKACXGPFFPTW" referencedColumnNames="ID" referencedTableName="REALM"/>
|
||||
<addForeignKeyConstraint baseColumnNames="COMPOSITE" baseTableName="COMPOSITE_ROLE" constraintName="FK_A63WVEKFTU8JO1PNJ81E7MCE2" referencedColumnNames="ID" referencedTableName="KEYCLOAK_ROLE"/>
|
||||
<addForeignKeyConstraint baseColumnNames="SESSION_ID" baseTableName="CLIENT_SESSION" constraintName="FK_B4AO2VCVAT6UKAU74WBWTFQO1" referencedColumnNames="ID" referencedTableName="USER_SESSION"/>
|
||||
<addForeignKeyConstraint baseColumnNames="USER_ID" baseTableName="USER_ROLE_MAPPING" constraintName="FK_C4FQV34P1MBYLLOXANG7B1Q3L" referencedColumnNames="ID" referencedTableName="USER_ENTITY"/>
|
||||
<addForeignKeyConstraint baseColumnNames="USERFEDERATIONPROVIDERS_ID" baseTableName="FED_PROVIDERS" constraintName="FK_DCCIRJLIPU1478VQC89DID88C" referencedColumnNames="ID" referencedTableName="USER_FEDERATION_PROVIDER"/>
|
||||
<addForeignKeyConstraint baseColumnNames="REALM_ID" baseTableName="REALM_DEFAULT_ROLES" constraintName="FK_EVUDB1PPW84OXFAX2DRS03ICC" referencedColumnNames="ID" referencedTableName="REALM"/>
|
||||
<addForeignKeyConstraint baseColumnNames="CHILD_ROLE" baseTableName="COMPOSITE_ROLE" constraintName="FK_GR7THLLB9LU8Q4VQA4524JJY8" referencedColumnNames="ID" referencedTableName="KEYCLOAK_ROLE"/>
|
||||
<addForeignKeyConstraint baseColumnNames="ROLE_ID" baseTableName="REALM_DEFAULT_ROLES" constraintName="FK_H4WPD7W4HSOOLNI3H0SW7BTJE" referencedColumnNames="ID" referencedTableName="KEYCLOAK_ROLE"/>
|
||||
<addForeignKeyConstraint baseColumnNames="REALM_ID" baseTableName="REALM_EVENTS_LISTENERS" constraintName="FK_H846O4H0W8EPX5NXEV9F5Y69J" referencedColumnNames="ID" referencedTableName="REALM"/>
|
||||
<addForeignKeyConstraint baseColumnNames="REALM_ID" baseTableName="REALM_APPLICATION" constraintName="FK_L5QGA3RFME47335JY8JXYXH3I" referencedColumnNames="ID" referencedTableName="CLIENT"/>
|
||||
<addForeignKeyConstraint baseColumnNames="CLIENT_ID" baseTableName="WEB_ORIGINS" constraintName="FK_LOJPHO213XCX4WNKOG82SSRFY" referencedColumnNames="ID" referencedTableName="CLIENT"/>
|
||||
<addForeignKeyConstraint baseColumnNames="APPLICATION_ID" baseTableName="APPLICATION_DEFAULT_ROLES" constraintName="FK_MAYLTS7KLWQW2H8M2B5JOYTKY" referencedColumnNames="ID" referencedTableName="CLIENT"/>
|
||||
<addForeignKeyConstraint baseColumnNames="CLIENT_ID" baseTableName="SCOPE_MAPPING" constraintName="FK_OUSE064PLMLR732LXJCN1Q5F1" referencedColumnNames="ID" referencedTableName="CLIENT"/>
|
||||
<addForeignKeyConstraint baseColumnNames="ROLE_ID" baseTableName="SCOPE_MAPPING" constraintName="FK_P3RH9GRKU11KQFRS4FLTT7RNQ" referencedColumnNames="ID" referencedTableName="KEYCLOAK_ROLE"/>
|
||||
<addForeignKeyConstraint baseColumnNames="REALM_ID" baseTableName="CLIENT" constraintName="FK_P56CTINXXB9GSK57FO49F9TAC" referencedColumnNames="ID" referencedTableName="REALM"/>
|
||||
<addForeignKeyConstraint baseColumnNames="USER_ID" baseTableName="CREDENTIAL" constraintName="FK_PFYR0GLASQYL0DEI3KL69R6V0" referencedColumnNames="ID" referencedTableName="USER_ENTITY"/>
|
||||
<addForeignKeyConstraint baseColumnNames="APPLICATION" baseTableName="KEYCLOAK_ROLE" constraintName="FK_PIMO5LE2C0RAL09FL8CM9WFW9" referencedColumnNames="ID" referencedTableName="CLIENT"/>
|
||||
<addForeignKeyConstraint baseColumnNames="MASTER_ADMIN_APP" baseTableName="REALM" constraintName="FK_RSAF444KK6QRKMS7N56AIWQ5Y" referencedColumnNames="ID" referencedTableName="CLIENT"/>
|
||||
<addForeignKeyConstraint baseColumnNames="REALM_ID" baseTableName="REALM_SOCIAL_CONFIG" constraintName="FK_SV5I3C2TI7G0G922FGE683SOV" referencedColumnNames="ID" referencedTableName="REALM"/>
|
||||
<addForeignKeyConstraint baseColumnNames="USER_FEDERATION_PROVIDER_ID" baseTableName="USER_FEDERATION_CONFIG" constraintName="FK_T13HPU1J94R2EBPEKR39X5EU5" referencedColumnNames="ID" referencedTableName="USER_FEDERATION_PROVIDER"/>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.2.xsd">
|
||||
<changeSet author="sthorger@redhat.com" id="1.1.0.Beta1">
|
||||
<delete tableName="CLIENT_SESSION_ROLE"/>
|
||||
<delete tableName="CLIENT_SESSION"/>
|
||||
<delete tableName="USER_SESSION"/>
|
||||
|
||||
<createTable tableName="CLIENT_ATTRIBUTES">
|
||||
<column name="CLIENT_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="VALUE" type="VARCHAR(2048)"/>
|
||||
<column name="NAME" type="VARCHAR(255)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<createTable tableName="CLIENT_SESSION_NOTE">
|
||||
<column name="NAME" type="VARCHAR(255)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="VALUE" type="VARCHAR(255)"/>
|
||||
<column name="CLIENT_SESSION" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<createTable tableName="APP_NODE_REGISTRATIONS">
|
||||
<column name="APPLICATION_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="VALUE" type="INT"/>
|
||||
<column name="NAME" type="VARCHAR(255)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<addColumn tableName="CLIENT_SESSION">
|
||||
<column name="AUTH_METHOD" type="VARCHAR(255)"/>
|
||||
</addColumn>
|
||||
<addColumn tableName="CLIENT">
|
||||
<column name="PROTOCOL" type="VARCHAR(255)"/>
|
||||
</addColumn>
|
||||
<addColumn tableName="CLIENT_SESSION">
|
||||
<column name="REALM_ID" type="VARCHAR(255)"/>
|
||||
</addColumn>
|
||||
<addColumn tableName="REALM">
|
||||
<column name="CERTIFICATE" type="VARCHAR(2048)"/>
|
||||
<column name="CODE_SECRET" type="VARCHAR(255)"/>
|
||||
</addColumn>
|
||||
<addColumn tableName="CLIENT">
|
||||
<column name="NODE_REREG_TIMEOUT" type="INT" defaultValueNumeric="0"/>
|
||||
</addColumn>
|
||||
<addPrimaryKey columnNames="CLIENT_ID, NAME" constraintName="CONSTRAINT_3C" tableName="CLIENT_ATTRIBUTES"/>
|
||||
<addPrimaryKey columnNames="CLIENT_SESSION, NAME" constraintName="CONSTRAINT_5E" tableName="CLIENT_SESSION_NOTE"/>
|
||||
<addPrimaryKey columnNames="APPLICATION_ID, NAME" constraintName="CONSTRAINT_84" tableName="APP_NODE_REGISTRATIONS"/>
|
||||
<addForeignKeyConstraint baseColumnNames="CLIENT_ID" baseTableName="CLIENT_ATTRIBUTES" constraintName="FK3C47C64BEACCA966" referencedColumnNames="ID" referencedTableName="CLIENT"/>
|
||||
<addForeignKeyConstraint baseColumnNames="CLIENT_SESSION" baseTableName="CLIENT_SESSION_NOTE" constraintName="FK5EDFB00FF51C2736" referencedColumnNames="ID" referencedTableName="CLIENT_SESSION"/>
|
||||
<addForeignKeyConstraint baseColumnNames="APPLICATION_ID" baseTableName="APP_NODE_REGISTRATIONS" constraintName="FK8454723BA992F594" referencedColumnNames="ID" referencedTableName="CLIENT"/>
|
||||
<customChange class="org.keycloak.connections.jpa.updater.liquibase.custom.AddRealmCodeSecret"/>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.2.xsd">
|
||||
<include file="META-INF/jpa-changelog-1.0.0.Final.xml"/>
|
||||
<include file="META-INF/jpa-changelog-1.1.0.Beta1.xml"/>
|
||||
</databaseChangeLog>
|
||||
+1
@@ -0,0 +1 @@
|
||||
org.keycloak.connections.jpa.updater.liquibase.LiquibaseJpaUpdaterProviderFactory
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.0.3.Final</version>
|
||||
<version>1.1.0.Beta1</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+81
-4
@@ -1,12 +1,20 @@
|
||||
package org.keycloak.connections.jpa;
|
||||
|
||||
import org.hibernate.ejb.AvailableSettings;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.Config;
|
||||
import org.keycloak.connections.jpa.updater.JpaUpdaterProvider;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
|
||||
import javax.naming.InitialContext;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.Persistence;
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -15,13 +23,15 @@ import java.util.Map;
|
||||
*/
|
||||
public class DefaultJpaConnectionProviderFactory implements JpaConnectionProviderFactory {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(DefaultJpaConnectionProviderFactory.class);
|
||||
|
||||
private volatile EntityManagerFactory emf;
|
||||
|
||||
private Config.Scope config;
|
||||
|
||||
@Override
|
||||
public JpaConnectionProvider create(KeycloakSession session) {
|
||||
lazyInit();
|
||||
lazyInit(session);
|
||||
|
||||
EntityManager em = emf.createEntityManager();
|
||||
em = PersistenceExceptionConverter.create(em);
|
||||
@@ -46,11 +56,17 @@ public class DefaultJpaConnectionProviderFactory implements JpaConnectionProvide
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
private void lazyInit() {
|
||||
private void lazyInit(KeycloakSession session) {
|
||||
if (emf == null) {
|
||||
synchronized (this) {
|
||||
if (emf == null) {
|
||||
logger.debug("Initializing JPA connections");
|
||||
|
||||
Connection connection = null;
|
||||
|
||||
String unitName = config.get("unitName");
|
||||
String databaseSchema = config.get("databaseSchema");
|
||||
|
||||
Map<String, Object> properties = new HashMap<String, Object>();
|
||||
|
||||
// Only load config from keycloak-server.json if unitName is not specified
|
||||
@@ -83,19 +99,80 @@ public class DefaultJpaConnectionProviderFactory implements JpaConnectionProvide
|
||||
properties.put("hibernate.dialect", driverDialect);
|
||||
}
|
||||
|
||||
String databaseSchema = config.get("databaseSchema", "validate");
|
||||
if (databaseSchema != null) {
|
||||
properties.put("hibernate.hbm2ddl.auto", databaseSchema);
|
||||
if (databaseSchema.equals("development-update")) {
|
||||
properties.put("hibernate.hbm2ddl.auto", "update");
|
||||
databaseSchema = null;
|
||||
} else if (databaseSchema.equals("development-validate")) {
|
||||
properties.put("hibernate.hbm2ddl.auto", "validate");
|
||||
databaseSchema = null;
|
||||
}
|
||||
}
|
||||
|
||||
properties.put("hibernate.show_sql", config.getBoolean("showSql", false));
|
||||
properties.put("hibernate.format_sql", config.getBoolean("formatSql", true));
|
||||
}
|
||||
|
||||
if (databaseSchema != null) {
|
||||
logger.trace("Updating database");
|
||||
|
||||
JpaUpdaterProvider updater = session.getProvider(JpaUpdaterProvider.class);
|
||||
connection = getConnection();
|
||||
|
||||
if (databaseSchema.equals("update")) {
|
||||
String currentVersion = null;
|
||||
try {
|
||||
ResultSet resultSet = connection.createStatement().executeQuery(updater.getCurrentVersionSql());
|
||||
if (resultSet.next()) {
|
||||
currentVersion = resultSet.getString(1);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
}
|
||||
|
||||
if (currentVersion == null || !JpaUpdaterProvider.LAST_VERSION.equals(currentVersion)) {
|
||||
updater.update(connection);
|
||||
} else {
|
||||
logger.debug("Database is up to date");
|
||||
}
|
||||
} else if (databaseSchema.equals("validate")) {
|
||||
updater.validate(connection);
|
||||
} else {
|
||||
throw new RuntimeException("Invalid value for databaseSchema: " + databaseSchema);
|
||||
}
|
||||
|
||||
logger.trace("Database update completed");
|
||||
}
|
||||
|
||||
logger.trace("Creating EntityManagerFactory");
|
||||
emf = Persistence.createEntityManagerFactory(unitName, properties);
|
||||
logger.trace("EntityManagerFactory created");
|
||||
|
||||
// Close after creating EntityManagerFactory to prevent in-mem databases from closing
|
||||
if (connection != null) {
|
||||
try {
|
||||
connection.close();
|
||||
} catch (SQLException e) {
|
||||
logger.warn(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Connection getConnection() {
|
||||
try {
|
||||
String dataSourceLookup = config.get("dataSource");
|
||||
if (dataSourceLookup != null) {
|
||||
DataSource dataSource = (DataSource) new InitialContext().lookup(dataSourceLookup);
|
||||
return dataSource.getConnection();
|
||||
} else {
|
||||
Class.forName(config.get("driver"));
|
||||
return DriverManager.getConnection(config.get("url"), config.get("user"), config.get("password"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to connect to database", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package org.keycloak.connections.jpa.updater;
|
||||
|
||||
import org.keycloak.provider.Provider;
|
||||
|
||||
import java.sql.Connection;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public interface JpaUpdaterProvider extends Provider {
|
||||
|
||||
public String FIRST_VERSION = "1.0.0.Final";
|
||||
|
||||
public String LAST_VERSION = "1.1.0.Beta1";
|
||||
|
||||
public String getCurrentVersionSql();
|
||||
|
||||
public void update(Connection connection);
|
||||
|
||||
public void validate(Connection connection);
|
||||
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package org.keycloak.connections.jpa.updater;
|
||||
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public interface JpaUpdaterProviderFactory extends ProviderFactory<JpaUpdaterProvider> {
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package org.keycloak.connections.jpa.updater;
|
||||
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.provider.Spi;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class JpaUpdaterSpi implements Spi {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "connectionsJpaUpdater";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Provider> getProviderClass() {
|
||||
return JpaUpdaterProvider.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends ProviderFactory> getProviderFactoryClass() {
|
||||
return JpaUpdaterProviderFactory.class;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,6 +21,7 @@
|
||||
<!-- JpaUserSessionProvider -->
|
||||
<class>org.keycloak.models.sessions.jpa.entities.ClientSessionEntity</class>
|
||||
<class>org.keycloak.models.sessions.jpa.entities.ClientSessionRoleEntity</class>
|
||||
<class>org.keycloak.models.sessions.jpa.entities.ClientSessionNoteEntity</class>
|
||||
<class>org.keycloak.models.sessions.jpa.entities.UserSessionEntity</class>
|
||||
<class>org.keycloak.models.sessions.jpa.entities.UsernameLoginFailureEntity</class>
|
||||
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
org.keycloak.connections.jpa.JpaConnectionSpi
|
||||
org.keycloak.connections.jpa.JpaConnectionSpi
|
||||
org.keycloak.connections.jpa.updater.JpaUpdaterSpi
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.0.3.Final</version>
|
||||
<version>1.1.0.Beta1</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+57
-5
@@ -2,6 +2,7 @@ package org.keycloak.connections.mongo;
|
||||
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.MongoClient;
|
||||
import com.mongodb.MongoClientOptions;
|
||||
import com.mongodb.MongoCredential;
|
||||
import com.mongodb.ServerAddress;
|
||||
import org.jboss.logging.Logger;
|
||||
@@ -9,8 +10,10 @@ import org.keycloak.Config;
|
||||
import org.keycloak.connections.mongo.api.MongoStore;
|
||||
import org.keycloak.connections.mongo.impl.MongoStoreImpl;
|
||||
import org.keycloak.connections.mongo.impl.context.TransactionMongoStoreInvocationContext;
|
||||
import org.keycloak.connections.mongo.updater.DefaultMongoUpdaterProvider;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
@@ -64,22 +67,32 @@ public class DefaultMongoConnectionFactoryProvider implements MongoConnectionPro
|
||||
String host = config.get("host", ServerAddress.defaultHost());
|
||||
int port = config.getInt("port", ServerAddress.defaultPort());
|
||||
String dbName = config.get("db", "keycloak");
|
||||
boolean clearOnStartup = config.getBoolean("clearOnStartup", false);
|
||||
|
||||
String user = config.get("user");
|
||||
String password = config.get("password");
|
||||
|
||||
MongoClientOptions clientOptions = getClientOptions();
|
||||
if (user != null && password != null) {
|
||||
MongoCredential credential = MongoCredential.createMongoCRCredential(user, dbName, password.toCharArray());
|
||||
client = new MongoClient(new ServerAddress(host, port), Collections.singletonList(credential));
|
||||
client = new MongoClient(new ServerAddress(host, port), Collections.singletonList(credential), clientOptions);
|
||||
} else {
|
||||
client = new MongoClient(host, port);
|
||||
client = new MongoClient(new ServerAddress(host, port), clientOptions);
|
||||
}
|
||||
|
||||
this.db = client.getDB(dbName);
|
||||
|
||||
this.mongoStore = new MongoStoreImpl(db, clearOnStartup, getManagedEntities());
|
||||
String databaseSchema = config.get("databaseSchema");
|
||||
if (databaseSchema != null) {
|
||||
if (databaseSchema.equals("update")) {
|
||||
new DefaultMongoUpdaterProvider().update(db);
|
||||
} else {
|
||||
throw new RuntimeException("Invalid value for databaseSchema: " + databaseSchema);
|
||||
}
|
||||
}
|
||||
|
||||
logger.infof("Initialized mongo model. host: %s, port: %d, db: %s, clearOnStartup: %b", host, port, dbName, clearOnStartup);
|
||||
this.mongoStore = new MongoStoreImpl(db, getManagedEntities());
|
||||
|
||||
logger.debugv("Initialized mongo model. host: %s, port: %d, db: %s", host, port, dbName);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -108,4 +121,43 @@ public class DefaultMongoConnectionFactoryProvider implements MongoConnectionPro
|
||||
return "default";
|
||||
}
|
||||
|
||||
protected MongoClientOptions getClientOptions() {
|
||||
MongoClientOptions.Builder builder = MongoClientOptions.builder();
|
||||
checkIntOption("connectionsPerHost", builder);
|
||||
checkIntOption("threadsAllowedToBlockForConnectionMultiplier", builder);
|
||||
checkIntOption("maxWaitTime", builder);
|
||||
checkIntOption("connectTimeout", builder);
|
||||
checkIntOption("socketTimeout", builder);
|
||||
checkBooleanOption("socketKeepAlive", builder);
|
||||
checkBooleanOption("autoConnectRetry", builder);
|
||||
if (config.getLong("maxAutoConnectRetryTime") != null) {
|
||||
builder.maxAutoConnectRetryTime(config.getLong("maxAutoConnectRetryTime"));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
protected void checkBooleanOption(String optionName, MongoClientOptions.Builder builder) {
|
||||
Boolean val = config.getBoolean(optionName);
|
||||
if (val != null) {
|
||||
try {
|
||||
Method m = MongoClientOptions.Builder.class.getMethod(optionName, boolean.class);
|
||||
m.invoke(builder, val);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Problem configuring boolean option " + optionName + " for mongo client. Ensure you used correct value true or false and if this option is supported by mongo driver", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void checkIntOption(String optionName, MongoClientOptions.Builder builder) {
|
||||
Integer val = config.getInt(optionName);
|
||||
if (val != null) {
|
||||
try {
|
||||
Method m = MongoClientOptions.Builder.class.getMethod(optionName, int.class);
|
||||
m.invoke(builder, val);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Problem configuring int option " + optionName + " for mongo client. Ensure you used correct value (number) and if this option is supported by mongo driver", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package org.keycloak.connections.mongo.api;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import static java.lang.annotation.ElementType.TYPE;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
@Target({TYPE})
|
||||
@Documented
|
||||
@Retention(RUNTIME)
|
||||
@Inherited
|
||||
public @interface MongoIndex {
|
||||
|
||||
String[] fields();
|
||||
|
||||
boolean unique() default false;
|
||||
|
||||
boolean sparse() default false;
|
||||
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package org.keycloak.connections.mongo.api;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import static java.lang.annotation.ElementType.TYPE;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
@Target({TYPE})
|
||||
@Documented
|
||||
@Retention(RUNTIME)
|
||||
@Inherited
|
||||
public @interface MongoIndexes {
|
||||
|
||||
MongoIndex[] value();
|
||||
|
||||
}
|
||||
+3
-69
@@ -11,8 +11,6 @@ import org.jboss.logging.Logger;
|
||||
import org.keycloak.connections.mongo.api.MongoCollection;
|
||||
import org.keycloak.connections.mongo.api.MongoEntity;
|
||||
import org.keycloak.connections.mongo.api.MongoIdentifiableEntity;
|
||||
import org.keycloak.connections.mongo.api.MongoIndex;
|
||||
import org.keycloak.connections.mongo.api.MongoIndexes;
|
||||
import org.keycloak.connections.mongo.api.MongoStore;
|
||||
import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
|
||||
import org.keycloak.connections.mongo.api.context.MongoTask;
|
||||
@@ -57,7 +55,7 @@ public class MongoStoreImpl implements MongoStore {
|
||||
new ConcurrentHashMap<Class<?>, EntityInfo>();
|
||||
|
||||
|
||||
public MongoStoreImpl(DB database, boolean clearCollectionsOnStartup, Class<?>[] managedEntityTypes) {
|
||||
public MongoStoreImpl(DB database, Class<?>[] managedEntityTypes) {
|
||||
this.database = database;
|
||||
|
||||
mapperRegistry = new MapperRegistry();
|
||||
@@ -86,13 +84,6 @@ public class MongoStoreImpl implements MongoStore {
|
||||
mapperRegistry.addAppObjectMapper(new MongoEntityMapper(this, mapperRegistry, type));
|
||||
mapperRegistry.addDBObjectMapper(new BasicDBObjectMapper(this, mapperRegistry, type));
|
||||
}
|
||||
|
||||
if (clearCollectionsOnStartup) {
|
||||
// dropDatabase();
|
||||
clearManagedCollections(managedEntityTypes);
|
||||
}
|
||||
|
||||
initManagedCollections(managedEntityTypes);
|
||||
}
|
||||
|
||||
protected void dropDatabase() {
|
||||
@@ -100,63 +91,6 @@ public class MongoStoreImpl implements MongoStore {
|
||||
logger.info("Database " + this.database.getName() + " dropped in MongoDB");
|
||||
}
|
||||
|
||||
// Don't drop database, but just clear all data in managed collections (useful for export/import or during development)
|
||||
protected void clearManagedCollections(Class<?>[] managedEntityTypes) {
|
||||
for (Class<?> clazz : managedEntityTypes) {
|
||||
DBCollection dbCollection = getDBCollectionForType(clazz);
|
||||
if (dbCollection != null) {
|
||||
dbCollection.remove(new BasicDBObject());
|
||||
logger.debug("Collection " + dbCollection.getName() + " cleared from " + this.database.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void initManagedCollections(Class<?>[] managedEntityTypes) {
|
||||
for (Class<?> clazz : managedEntityTypes) {
|
||||
EntityInfo entityInfo = getEntityInfo(clazz);
|
||||
String dbCollectionName = entityInfo.getDbCollectionName();
|
||||
if (dbCollectionName != null && !database.collectionExists(dbCollectionName)) {
|
||||
DBCollection dbCollection = database.getCollection(dbCollectionName);
|
||||
|
||||
logger.debug("Created collection " + dbCollection.getName() + " in " + this.database.getName());
|
||||
|
||||
MongoIndex index = clazz.getAnnotation(MongoIndex.class);
|
||||
if (index != null) {
|
||||
createIndex(dbCollection, index);
|
||||
}
|
||||
|
||||
MongoIndexes indexes = clazz.getAnnotation(MongoIndexes.class);
|
||||
if (indexes != null) {
|
||||
for (MongoIndex i : indexes.value()) {
|
||||
createIndex(dbCollection, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void createIndex(DBCollection dbCollection, MongoIndex index) {
|
||||
BasicDBObject fields = new BasicDBObject();
|
||||
for (String f : index.fields()) {
|
||||
fields.put(f, 1);
|
||||
}
|
||||
|
||||
boolean unique = index.unique();
|
||||
boolean sparse = index.sparse();
|
||||
|
||||
BasicDBObject options = new BasicDBObject();
|
||||
if (unique) {
|
||||
options.put("unique", unique);
|
||||
}
|
||||
if (sparse) {
|
||||
options.put("sparse", sparse);
|
||||
}
|
||||
|
||||
dbCollection.ensureIndex(fields, options);
|
||||
|
||||
logger.debug("Created index " + fields + "(options: " + options + ") on " + dbCollection.getName() + " in " + this.database.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context) {
|
||||
Class<? extends MongoEntity> clazz = entity.getClass();
|
||||
@@ -325,7 +259,7 @@ public class MongoStoreImpl implements MongoStore {
|
||||
DBCollection dbCollection = getDBCollectionForType(type);
|
||||
BasicDBObject dbQuery = new BasicDBObject("_id", id);
|
||||
dbCollection.remove(dbQuery);
|
||||
logger.info("Entity of type: " + type + ", id: " + id + " removed from MongoDB.");
|
||||
//logger.debugf("Entity of type: %s , id: %s removed from MongoDB.", type, id);
|
||||
|
||||
context.addRemovedEntity(found);
|
||||
return true;
|
||||
@@ -341,7 +275,7 @@ public class MongoStoreImpl implements MongoStore {
|
||||
} else {
|
||||
DBCollection dbCollection = getDBCollectionForType(type);
|
||||
dbCollection.remove(query);
|
||||
logger.info("Removed " + foundObjects.size() + " entities of type: " + type + ", query: " + query);
|
||||
//logger.debug("Removed %d" + foundObjects.size() + " entities of type: " + type + ", query: " + query);
|
||||
|
||||
for (MongoIdentifiableEntity found : foundObjects) {
|
||||
context.addRemovedEntity(found);;
|
||||
|
||||
+8
-3
@@ -8,7 +8,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* For now, there is support just for convert to Map<String, String>
|
||||
* For now, there is support just for convert to Map<String, simpleType>
|
||||
*
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
@@ -18,10 +18,15 @@ public class BasicDBObjectToMapMapper implements Mapper<BasicDBObject, Map> {
|
||||
public Map convertObject(MapperContext<BasicDBObject, Map> context) {
|
||||
BasicDBObject dbObjectToConvert = context.getObjectToConvert();
|
||||
|
||||
HashMap<String, String> result = new HashMap<String, String>();
|
||||
HashMap<String, Object> result = new HashMap<String, Object>();
|
||||
for (Map.Entry<String, Object> entry : dbObjectToConvert.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
String value = (String)entry.getValue();
|
||||
Object value = entry.getValue();
|
||||
|
||||
// Workaround as manually inserted numbers into mongo may be treated as "Double"
|
||||
if (value instanceof Double && context.getGenericTypes().get(1) == Integer.class) {
|
||||
value = ((Double)value).intValue();
|
||||
}
|
||||
|
||||
if (key.contains(MapMapper.DOT_PLACEHOLDER)) {
|
||||
key = key.replaceAll(MapMapper.DOT_PLACEHOLDER, ".");
|
||||
|
||||
+2
-2
@@ -8,7 +8,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* For now, we support just convert from Map<String, String>
|
||||
* For now, we support just convert from Map<String, simpleType>
|
||||
*
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
@@ -31,7 +31,7 @@ public class MapMapper<T extends Map> implements Mapper<T, BasicDBObject> {
|
||||
Set<Map.Entry> entries = objectToConvert.entrySet();
|
||||
for (Map.Entry entry : entries) {
|
||||
String key = (String)entry.getKey();
|
||||
String value = (String)entry.getValue();
|
||||
Object value = entry.getValue();
|
||||
|
||||
if (key.contains(".")) {
|
||||
key = key.replaceAll("\\.", DOT_PLACEHOLDER);
|
||||
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
package org.keycloak.connections.mongo.updater;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.DBCursor;
|
||||
import com.mongodb.DBObject;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.connections.mongo.updater.updates.Update;
|
||||
import org.keycloak.connections.mongo.updater.updates.Update1_0_0_Final;
|
||||
import org.keycloak.connections.mongo.updater.updates.Update1_1_0_Beta1;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class DefaultMongoUpdaterProvider implements MongoUpdaterProvider {
|
||||
|
||||
public static final Logger log = Logger.getLogger(DefaultMongoUpdaterProvider.class);
|
||||
|
||||
public static final String CHANGE_LOG_COLLECTION = "databaseChangeLog";
|
||||
|
||||
private Class<? extends Update>[] updates = new Class[]{
|
||||
Update1_0_0_Final.class,
|
||||
Update1_1_0_Beta1.class
|
||||
};
|
||||
|
||||
@Override
|
||||
public void update(DB db) {
|
||||
log.debug("Starting database update");
|
||||
try {
|
||||
boolean changeLogExists = db.collectionExists(CHANGE_LOG_COLLECTION);
|
||||
boolean realmExists = db.collectionExists("realms");
|
||||
|
||||
DBCollection changeLog = db.getCollection(CHANGE_LOG_COLLECTION);
|
||||
|
||||
List<String> executed = new LinkedList<String>();
|
||||
if (!changeLogExists && realmExists) {
|
||||
Update1_0_0_Final u = new Update1_0_0_Final();
|
||||
executed.add(u.getId());
|
||||
createLog(changeLog, u, 1);
|
||||
} else if (changeLogExists) {
|
||||
DBCursor cursor = changeLog.find().sort(new BasicDBObject("orderExecuted", 1));
|
||||
while (cursor.hasNext()) {
|
||||
executed.add((String) cursor.next().get("_id"));
|
||||
}
|
||||
}
|
||||
|
||||
List<Update> updatesToRun = new LinkedList<Update>();
|
||||
for (Class<? extends Update> updateClass : updates) {
|
||||
Update u = updateClass.newInstance();
|
||||
if (!executed.contains(u.getId())) {
|
||||
updatesToRun.add(u);
|
||||
}
|
||||
}
|
||||
|
||||
if (!updatesToRun.isEmpty()) {
|
||||
if (executed.isEmpty()) {
|
||||
log.info("Initializing database schema");
|
||||
} else {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.infov("Updating database from {0} to {1}", executed.get(executed.size() - 1), updatesToRun.get(updatesToRun.size() - 1).getId());
|
||||
} else {
|
||||
log.debugv("Updating database");
|
||||
}
|
||||
}
|
||||
|
||||
int order = executed.size();
|
||||
for (Update u : updatesToRun) {
|
||||
log.debugv("Executing updates for {0}", u.getId());
|
||||
|
||||
u.setLog(log);
|
||||
u.setDb(db);
|
||||
u.update();
|
||||
|
||||
createLog(changeLog, u, ++order);
|
||||
|
||||
log.debugv("Completed updates for {0}", u.getId());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to update database", e);
|
||||
}
|
||||
log.debug("Completed database update");
|
||||
}
|
||||
|
||||
private void createLog(DBCollection changeLog, Update update, int orderExecuted) {
|
||||
changeLog.insert(new BasicDBObject("_id", update.getId()).append("dateExecuted", new Date()).append("orderExecuted", orderExecuted));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package org.keycloak.connections.mongo.updater;
|
||||
|
||||
import org.keycloak.Config;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class DefaultMongoUpdaterProviderFactory implements MongoUpdaterProviderFactory {
|
||||
|
||||
@Override
|
||||
public MongoUpdaterProvider create(KeycloakSession session) {
|
||||
return new DefaultMongoUpdaterProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Config.Scope config) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "default";
|
||||
}
|
||||
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package org.keycloak.connections.mongo.updater;
|
||||
|
||||
import com.mongodb.DB;
|
||||
import org.keycloak.provider.Provider;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public interface MongoUpdaterProvider extends Provider {
|
||||
|
||||
public void update(DB db);
|
||||
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package org.keycloak.connections.mongo.updater;
|
||||
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public interface MongoUpdaterProviderFactory extends ProviderFactory<MongoUpdaterProvider> {
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package org.keycloak.connections.mongo.updater;
|
||||
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.provider.Spi;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class MongoUpdaterSpi implements Spi {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "connectionsMongoUpdater";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Provider> getProviderClass() {
|
||||
return MongoUpdaterProvider.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends ProviderFactory> getProviderFactoryClass() {
|
||||
return MongoUpdaterProviderFactory.class;
|
||||
}
|
||||
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
package org.keycloak.connections.mongo.updater.updates;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.DBCollection;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public abstract class Update {
|
||||
|
||||
protected DB db;
|
||||
|
||||
protected Logger log;
|
||||
|
||||
public abstract String getId();
|
||||
|
||||
public abstract void update() throws ClassNotFoundException;
|
||||
|
||||
protected DBCollection createCollection(String name) {
|
||||
if (db.collectionExists(name)) {
|
||||
throw new RuntimeException("Failed to create collection {0}: collection already exists");
|
||||
}
|
||||
|
||||
DBCollection col = db.getCollection(name);
|
||||
log.debugv("Created collection {0}", name);
|
||||
return col;
|
||||
}
|
||||
|
||||
protected void ensureIndex(String name, String field, boolean unique, boolean sparse) {
|
||||
ensureIndex(name, new String[]{field}, unique, sparse);
|
||||
}
|
||||
|
||||
protected void ensureIndex(String name, String[] fields, boolean unique, boolean sparse) {
|
||||
DBCollection col = db.getCollection(name);
|
||||
|
||||
BasicDBObject o = new BasicDBObject();
|
||||
for (String f : fields) {
|
||||
o.append(f, 1);
|
||||
}
|
||||
|
||||
col.ensureIndex(o, new BasicDBObject("unique", unique).append("sparse", sparse));
|
||||
log.debugv("Created index {0}, fields={1}, unique={2}, sparse={3}", name, Arrays.toString(fields), unique, sparse);
|
||||
}
|
||||
|
||||
protected void deleteEntries(String collection) {
|
||||
db.getCollection(collection).remove(new BasicDBObject());
|
||||
log.debugv("Deleted entries from {0}", collection);
|
||||
}
|
||||
|
||||
public void setLog(Logger log) {
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
public void setDb(DB db) {
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package org.keycloak.connections.mongo.updater.updates;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBCollection;
|
||||
import org.keycloak.connections.mongo.updater.DefaultMongoUpdaterProvider;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class Update1_0_0_Final extends Update {
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "1.0.0.Final";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() throws ClassNotFoundException {
|
||||
DBCollection realmsCollection = db.getCollection("realms");
|
||||
realmsCollection.ensureIndex(new BasicDBObject("name", 1), new BasicDBObject("unique", true));
|
||||
|
||||
DefaultMongoUpdaterProvider.log.debugv("Created collection {0}", "realms");
|
||||
|
||||
createCollection("users");
|
||||
ensureIndex("users", new String[] { "realmId", "username"}, true, false);
|
||||
ensureIndex("users", "emailIndex", true, true);
|
||||
|
||||
createCollection("roles");
|
||||
ensureIndex("roles", "nameIndex", true, false);
|
||||
|
||||
createCollection("applications");
|
||||
ensureIndex("applications", new String[]{"realmId", "name"}, true, false);
|
||||
|
||||
createCollection("oauthClients");
|
||||
ensureIndex("oauthClients", new String[] { "realmId", "name"}, true, false);
|
||||
|
||||
createCollection("userFailures");
|
||||
|
||||
createCollection("sessions");
|
||||
|
||||
createCollection("clientSessions");
|
||||
}
|
||||
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package org.keycloak.connections.mongo.updater.updates;
|
||||
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.DBCursor;
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.QueryBuilder;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class Update1_1_0_Beta1 extends Update {
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "1.1.0.Beta1";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
deleteEntries("clientSessions");
|
||||
deleteEntries("sessions");
|
||||
|
||||
addRealmCodeSecret();
|
||||
}
|
||||
|
||||
private void addRealmCodeSecret() {
|
||||
DBCollection realms = db.getCollection("realms");
|
||||
|
||||
DBObject query = new QueryBuilder()
|
||||
.and("codeSecret").is(null).get();
|
||||
|
||||
DBCursor objects = realms.find(query);
|
||||
while (objects.hasNext()) {
|
||||
DBObject object = objects.next();
|
||||
object.put("codeSecret", KeycloakModelUtils.generateCodeSecret());
|
||||
realms.save(object);
|
||||
|
||||
log.debugv("Added realm.codeSecret, id={0}", object.get("id"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+3
-1
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.0.3.Final</version>
|
||||
<version>1.1.0.Beta1</version>
|
||||
</parent>
|
||||
<name>Connections Parent</name>
|
||||
<description/>
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
<modules>
|
||||
<module>jpa</module>
|
||||
<module>jpa-liquibase</module>
|
||||
<module>infinispan</module>
|
||||
<module>mongo</module>
|
||||
</modules>
|
||||
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.0.3.Final</version>
|
||||
<version>1.1.0.Beta1</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.0.3.Final</version>
|
||||
<version>1.1.0.Beta1</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.keycloak;
|
||||
|
||||
import org.keycloak.enums.RelativeUrlsUsed;
|
||||
import org.keycloak.util.KeycloakUriBuilder;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -19,7 +20,7 @@ public class AbstractOAuthClient {
|
||||
protected String authUrl;
|
||||
protected String codeUrl;
|
||||
protected String refreshUrl;
|
||||
protected boolean relativeUrls;
|
||||
protected RelativeUrlsUsed relativeUrlsUsed;
|
||||
protected String scope;
|
||||
protected String stateCookieName = OAUTH_TOKEN_REQUEST_STATE;
|
||||
protected String stateCookiePath;
|
||||
@@ -101,12 +102,12 @@ public class AbstractOAuthClient {
|
||||
this.publicClient = publicClient;
|
||||
}
|
||||
|
||||
public boolean isRelativeUrls() {
|
||||
return relativeUrls;
|
||||
public RelativeUrlsUsed getRelativeUrlsUsed() {
|
||||
return relativeUrlsUsed;
|
||||
}
|
||||
|
||||
public void setRelativeUrls(boolean relativeUrls) {
|
||||
this.relativeUrls = relativeUrls;
|
||||
public void setRelativeUrlsUsed(RelativeUrlsUsed relativeUrlsUsed) {
|
||||
this.relativeUrlsUsed = relativeUrlsUsed;
|
||||
}
|
||||
|
||||
protected String stripOauthParametersFromRedirect(String uri) {
|
||||
|
||||
@@ -121,6 +121,17 @@ public class Config {
|
||||
return v != null ? Boolean.parseBoolean(v) : defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Scope scope(String... scope) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(prefix + ".");
|
||||
for (String s : scope) {
|
||||
sb.append(s);
|
||||
sb.append(".");
|
||||
}
|
||||
return new SystemPropertiesScope(sb.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -146,5 +157,7 @@ public class Config {
|
||||
|
||||
Boolean getBoolean(String key, Boolean defaultValue);
|
||||
|
||||
Scope scope(String... scope);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -7,16 +7,16 @@ import java.security.Principal;
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class KeycloakPrincipal implements Principal, Serializable {
|
||||
public class KeycloakPrincipal<T extends KeycloakSecurityContext> implements Principal, Serializable {
|
||||
protected final String name;
|
||||
protected final KeycloakSecurityContext context;
|
||||
protected final T context;
|
||||
|
||||
public KeycloakPrincipal(String name, KeycloakSecurityContext context) {
|
||||
public KeycloakPrincipal(String name, T context) {
|
||||
this.name = name;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public KeycloakSecurityContext getKeycloakSecurityContext() {
|
||||
public T getKeycloakSecurityContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,12 @@ package org.keycloak;
|
||||
|
||||
import org.keycloak.representations.AccessToken;
|
||||
import org.keycloak.representations.IDToken;
|
||||
import org.keycloak.util.Base64Url;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
@@ -11,10 +16,12 @@ import java.io.Serializable;
|
||||
*/
|
||||
public class KeycloakSecurityContext implements Serializable {
|
||||
protected String tokenString;
|
||||
protected AccessToken token;
|
||||
protected IDToken idToken;
|
||||
protected String idTokenString;
|
||||
|
||||
// Don't store parsed tokens into HTTP session
|
||||
protected transient AccessToken token;
|
||||
protected transient IDToken idToken;
|
||||
|
||||
public KeycloakSecurityContext() {
|
||||
}
|
||||
|
||||
@@ -40,4 +47,36 @@ public class KeycloakSecurityContext implements Serializable {
|
||||
public String getIdTokenString() {
|
||||
return idTokenString;
|
||||
}
|
||||
|
||||
public String getRealm() {
|
||||
// Assumption that issuer contains realm name
|
||||
return token.getIssuer();
|
||||
}
|
||||
|
||||
// SERIALIZATION
|
||||
|
||||
private void writeObject(ObjectOutputStream out) throws IOException {
|
||||
out.defaultWriteObject();
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
in.defaultReadObject();
|
||||
|
||||
token = parseToken(tokenString, AccessToken.class);
|
||||
idToken = parseToken(idTokenString, IDToken.class);
|
||||
}
|
||||
|
||||
// Just decode token without any verifications
|
||||
private <T> T parseToken(String encoded, Class<T> clazz) throws IOException {
|
||||
if (encoded == null)
|
||||
return null;
|
||||
|
||||
String[] parts = encoded.split("\\.");
|
||||
if (parts.length < 2 || parts.length > 3) throw new IllegalArgumentException("Parsing error");
|
||||
|
||||
byte[] bytes = Base64Url.decode(parts[1]);
|
||||
return JsonSerialization.readValue(bytes, clazz);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -35,7 +35,7 @@ public class RSATokenVerifier {
|
||||
if (user == null) {
|
||||
throw new VerificationException("Token user was null.");
|
||||
}
|
||||
if (!realm.equals(token.getAudience())) {
|
||||
if (!realm.equals(token.getIssuer())) {
|
||||
throw new VerificationException("Token audience doesn't match domain.");
|
||||
|
||||
}
|
||||
|
||||
@@ -6,12 +6,14 @@ package org.keycloak;
|
||||
*/
|
||||
public interface ServiceUrlConstants {
|
||||
|
||||
public static final String TOKEN_SERVICE_LOGIN_PATH = "/realms/{realm-name}/tokens/login";
|
||||
public static final String TOKEN_SERVICE_ACCESS_CODE_PATH = "/realms/{realm-name}/tokens/access/codes";
|
||||
public static final String TOKEN_SERVICE_REFRESH_PATH = "/realms/{realm-name}/tokens/refresh";
|
||||
public static final String TOKEN_SERVICE_LOGOUT_PATH = "/realms/{realm-name}/tokens/logout";
|
||||
public static final String TOKEN_SERVICE_DIRECT_GRANT_PATH = "/realms/{realm-name}/tokens/grants/access";
|
||||
public static final String TOKEN_SERVICE_LOGIN_PATH = "/realms/{realm-name}/protocol/openid-connect/login";
|
||||
public static final String TOKEN_SERVICE_ACCESS_CODE_PATH = "/realms/{realm-name}/protocol/openid-connect/access/codes";
|
||||
public static final String TOKEN_SERVICE_REFRESH_PATH = "/realms/{realm-name}/protocol/openid-connect/refresh";
|
||||
public static final String TOKEN_SERVICE_LOGOUT_PATH = "/realms/{realm-name}/protocol/openid-connect/logout";
|
||||
public static final String TOKEN_SERVICE_DIRECT_GRANT_PATH = "/realms/{realm-name}/protocol/openid-connect/grants/access";
|
||||
public static final String ACCOUNT_SERVICE_PATH = "/realms/{realm-name}/account";
|
||||
public static final String REALM_INFO_PATH = "/realms/{realm-name}";
|
||||
public static final String CLIENTS_MANAGEMENT_REGISTER_NODE_PATH = "/realms/{realm-name}/clients-managements/register-node";
|
||||
public static final String CLIENTS_MANAGEMENT_UNREGISTER_NODE_PATH = "/realms/{realm-name}/clients-managements/unregister-node";
|
||||
|
||||
}
|
||||
@@ -10,12 +10,23 @@ public interface AdapterConstants {
|
||||
public static final String K_LOGOUT = "k_logout";
|
||||
public static final String K_VERSION = "k_version";
|
||||
public static final String K_PUSH_NOT_BEFORE = "k_push_not_before";
|
||||
public static final String K_GET_USER_STATS = "k_get_user_stats";
|
||||
public static final String K_GET_SESSION_STATS = "k_get_session_stats";
|
||||
public static final String K_TEST_AVAILABLE = "k_test_available";
|
||||
public static final String K_QUERY_BEARER_TOKEN = "k_query_bearer_token";
|
||||
|
||||
// This param name is defined again in Keycloak Subsystem class
|
||||
// org.keycloak.subsystem.extensionKeycloakAdapterConfigDeploymentProcessor. We have this value in
|
||||
// two places to avoid dependency between Keycloak Subsystem and Keyclaok Undertow Integration.
|
||||
String AUTH_DATA_PARAM_NAME = "org.keycloak.json.adapterConfig";
|
||||
|
||||
// Attribute passed in codeToToken request from adapter to Keycloak and saved in ClientSession. Contains ID of HttpSession on adapter
|
||||
public static final String APPLICATION_SESSION_STATE = "application_session_state";
|
||||
|
||||
// Attribute passed in codeToToken request from adapter to Keycloak and saved in ClientSession. Contains hostname of adapter where HttpSession is served
|
||||
public static final String APPLICATION_SESSION_HOST = "application_session_host";
|
||||
|
||||
// Attribute passed in registerNode request for register new application cluster node once he joined cluster
|
||||
public static final String APPLICATION_CLUSTER_HOST = "application_cluster_host";
|
||||
|
||||
// Cookie used on adapter side to store token info. Used only when tokenStore is 'COOKIE'
|
||||
public static final String KEYCLOAK_ADAPTER_STATE_COOKIE = "KEYCLOAK_ADAPTER_STATE";
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package org.keycloak.enums;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public enum RelativeUrlsUsed {
|
||||
|
||||
/**
|
||||
* Always use relative URI and resolve them later based on browser HTTP request
|
||||
*/
|
||||
ALL_REQUESTS,
|
||||
|
||||
/**
|
||||
* Use relative Uris just for browser requests and resolve those based on browser HTTP requests.
|
||||
* Backend request (like refresh token request, codeToToken request etc) will use the URI based on current hostname
|
||||
*/
|
||||
BROWSER_ONLY,
|
||||
|
||||
/**
|
||||
* Relative Uri not used. Configuration contains absolute URI
|
||||
*/
|
||||
NEVER;
|
||||
|
||||
public boolean useRelative(boolean isBrowserReq) {
|
||||
switch (this) {
|
||||
case ALL_REQUESTS:
|
||||
return true;
|
||||
case NEVER:
|
||||
return false;
|
||||
case BROWSER_ONLY:
|
||||
return isBrowserReq;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.keycloak.enums;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public enum TokenStore {
|
||||
SESSION,
|
||||
COOKIE
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package org.keycloak.representations;
|
||||
import org.codehaus.jackson.annotate.JsonIgnore;
|
||||
import org.codehaus.jackson.annotate.JsonProperty;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
@@ -13,7 +14,7 @@ import java.util.Set;
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class AccessToken extends IDToken {
|
||||
public static class Access {
|
||||
public static class Access implements Serializable {
|
||||
@JsonProperty("roles")
|
||||
protected Set<String> roles;
|
||||
@JsonProperty("verify_caller")
|
||||
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
package org.keycloak.representations.adapters.action;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Result of the "global" request (like push notBefore or logoutAll), which is send to all cluster nodes
|
||||
*
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class GlobalRequestResult {
|
||||
|
||||
private List<String> successRequests;
|
||||
private List<String> failedRequests;
|
||||
|
||||
public void addSuccessRequest(String reqUri) {
|
||||
if (successRequests == null) {
|
||||
successRequests = new ArrayList<String>();
|
||||
}
|
||||
successRequests.add(reqUri);
|
||||
}
|
||||
|
||||
public void addFailedRequest(String reqUri) {
|
||||
if (failedRequests == null) {
|
||||
failedRequests = new ArrayList<String>();
|
||||
}
|
||||
failedRequests.add(reqUri);
|
||||
}
|
||||
|
||||
public void addAllSuccessRequests(List<String> reqUris) {
|
||||
if (successRequests == null) {
|
||||
successRequests = new ArrayList<String>();
|
||||
}
|
||||
successRequests.addAll(reqUris);
|
||||
}
|
||||
|
||||
public void addAllFailedRequests(List<String> reqUris) {
|
||||
if (failedRequests == null) {
|
||||
failedRequests = new ArrayList<String>();
|
||||
}
|
||||
failedRequests.addAll(reqUris);
|
||||
}
|
||||
|
||||
public void addAll(GlobalRequestResult merged) {
|
||||
if (merged.getSuccessRequests() != null && merged.getSuccessRequests().size() > 0) {
|
||||
addAllSuccessRequests(merged.getSuccessRequests());
|
||||
}
|
||||
if (merged.getFailedRequests() != null && merged.getFailedRequests().size() > 0) {
|
||||
addAllFailedRequests(merged.getFailedRequests());
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getSuccessRequests() {
|
||||
return successRequests;
|
||||
}
|
||||
|
||||
public List<String> getFailedRequests() {
|
||||
return failedRequests;
|
||||
}
|
||||
}
|
||||
@@ -1,40 +1,25 @@
|
||||
package org.keycloak.representations.adapters.action;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class LogoutAction extends AdminAction {
|
||||
public static final String LOGOUT = "LOGOUT";
|
||||
protected String user;
|
||||
private String session;
|
||||
protected List<String> adapterSessionIds;
|
||||
protected int notBefore;
|
||||
|
||||
public LogoutAction() {
|
||||
}
|
||||
|
||||
public LogoutAction(String id, int expiration, String resource, String user, String session, int notBefore) {
|
||||
public LogoutAction(String id, int expiration, String resource, List<String> adapterSessionIds, int notBefore) {
|
||||
super(id, expiration, resource, LOGOUT);
|
||||
this.user = user;
|
||||
this.session = session;
|
||||
this.adapterSessionIds = adapterSessionIds;
|
||||
this.notBefore = notBefore;
|
||||
}
|
||||
|
||||
public String getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(String user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public String getSession() {
|
||||
return session;
|
||||
}
|
||||
|
||||
public void setSession(String session) {
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
public int getNotBefore() {
|
||||
return notBefore;
|
||||
@@ -44,6 +29,10 @@ public class LogoutAction extends AdminAction {
|
||||
this.notBefore = notBefore;
|
||||
}
|
||||
|
||||
public List<String> getAdapterSessionIds() {
|
||||
return adapterSessionIds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate() {
|
||||
return LOGOUT.equals(action);
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
package org.keycloak.representations.adapters.action;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class SessionStats {
|
||||
protected int activeSessions;
|
||||
protected int activeUsers;
|
||||
protected Map<String, UserStats> users;
|
||||
|
||||
public int getActiveSessions() {
|
||||
return activeSessions;
|
||||
}
|
||||
|
||||
public void setActiveSessions(int activeSessions) {
|
||||
this.activeSessions = activeSessions;
|
||||
}
|
||||
|
||||
public int getActiveUsers() {
|
||||
return activeUsers;
|
||||
}
|
||||
|
||||
public void setActiveUsers(int activeUsers) {
|
||||
this.activeUsers = activeUsers;
|
||||
}
|
||||
|
||||
public Map<String, UserStats> getUsers() {
|
||||
return users;
|
||||
}
|
||||
|
||||
public void setUsers(Map<String, UserStats> users) {
|
||||
this.users = users;
|
||||
}
|
||||
}
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
package org.keycloak.representations.adapters.action;
|
||||
|
||||
/**
|
||||
* Query session stats.
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class SessionStatsAction extends AdminAction {
|
||||
|
||||
public static final String SESSION_STATS = "SESSION_STATS";
|
||||
|
||||
protected boolean listUsers;
|
||||
|
||||
public SessionStatsAction() {
|
||||
}
|
||||
|
||||
public SessionStatsAction(String id, int expiration, String resource) {
|
||||
super(id, expiration, resource, SESSION_STATS);
|
||||
}
|
||||
|
||||
public boolean isListUsers() {
|
||||
return listUsers;
|
||||
}
|
||||
|
||||
public void setListUsers(boolean listUsers) {
|
||||
this.listUsers = listUsers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate() {
|
||||
return SESSION_STATS.equals(action);
|
||||
}
|
||||
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package org.keycloak.representations.adapters.action;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class TestAvailabilityAction extends AdminAction {
|
||||
|
||||
public static final String TEST_AVAILABILITY = "TEST_AVAILABILITY";
|
||||
|
||||
public TestAvailabilityAction() {
|
||||
}
|
||||
|
||||
public TestAvailabilityAction(String id, int expiration, String resource) {
|
||||
super(id, expiration, resource, TEST_AVAILABILITY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate() {
|
||||
return TEST_AVAILABILITY.equals(action);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package org.keycloak.representations.adapters.action;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class UserStats {
|
||||
protected boolean loggedIn;
|
||||
protected long whenLoggedIn;
|
||||
|
||||
public boolean isLoggedIn() {
|
||||
return loggedIn;
|
||||
}
|
||||
|
||||
public void setLoggedIn(boolean loggedIn) {
|
||||
this.loggedIn = loggedIn;
|
||||
}
|
||||
|
||||
public long getWhenLoggedIn() {
|
||||
return whenLoggedIn;
|
||||
}
|
||||
|
||||
public void setWhenLoggedIn(long whenLoggedIn) {
|
||||
this.whenLoggedIn = whenLoggedIn;
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package org.keycloak.representations.adapters.action;
|
||||
|
||||
/**
|
||||
* Query session stats.
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class UserStatsAction extends AdminAction {
|
||||
|
||||
public static final String USER_STATS = "USER_STATS";
|
||||
protected String user;
|
||||
|
||||
public UserStatsAction() {
|
||||
}
|
||||
|
||||
public UserStatsAction(String id, int expiration, String resource, String user) {
|
||||
super(id, expiration, resource, USER_STATS);
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public String getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate() {
|
||||
return USER_STATS.equals(action);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,13 +10,15 @@ import org.codehaus.jackson.annotate.JsonPropertyOrder;
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
@JsonPropertyOrder({"realm", "realm-public-key", "auth-server-url", "ssl-required",
|
||||
"resource", "credentials",
|
||||
"resource", "public-client", "credentials",
|
||||
"use-resource-role-mappings",
|
||||
"enable-cors", "cors-max-age", "cors-allowed-methods",
|
||||
"expose-token", "bearer-only",
|
||||
"connection-pool-size",
|
||||
"allow-any-hostname", "disable-trust-manager", "truststore", "truststore-password",
|
||||
"client-keystore", "client-keystore-password", "client-key-password"
|
||||
"client-keystore", "client-keystore-password", "client-key-password",
|
||||
"auth-server-url-for-backend-requests", "always-refresh-token",
|
||||
"register-node-at-startup", "register-node-period", "token-store", "principal-attribute"
|
||||
})
|
||||
public class AdapterConfig extends BaseAdapterConfig {
|
||||
|
||||
@@ -36,6 +38,18 @@ public class AdapterConfig extends BaseAdapterConfig {
|
||||
protected String clientKeyPassword;
|
||||
@JsonProperty("connection-pool-size")
|
||||
protected int connectionPoolSize = 20;
|
||||
@JsonProperty("auth-server-url-for-backend-requests")
|
||||
protected String authServerUrlForBackendRequests;
|
||||
@JsonProperty("always-refresh-token")
|
||||
protected boolean alwaysRefreshToken = false;
|
||||
@JsonProperty("register-node-at-startup")
|
||||
protected boolean registerNodeAtStartup = false;
|
||||
@JsonProperty("register-node-period")
|
||||
protected int registerNodePeriod = -1;
|
||||
@JsonProperty("token-store")
|
||||
protected String tokenStore;
|
||||
@JsonProperty("principal-attribute")
|
||||
protected String principalAttribute;
|
||||
|
||||
public boolean isAllowAnyHostname() {
|
||||
return allowAnyHostname;
|
||||
@@ -101,4 +115,51 @@ public class AdapterConfig extends BaseAdapterConfig {
|
||||
this.connectionPoolSize = connectionPoolSize;
|
||||
}
|
||||
|
||||
public String getAuthServerUrlForBackendRequests() {
|
||||
return authServerUrlForBackendRequests;
|
||||
}
|
||||
|
||||
public void setAuthServerUrlForBackendRequests(String authServerUrlForBackendRequests) {
|
||||
this.authServerUrlForBackendRequests = authServerUrlForBackendRequests;
|
||||
}
|
||||
|
||||
public boolean isAlwaysRefreshToken() {
|
||||
return alwaysRefreshToken;
|
||||
}
|
||||
|
||||
public void setAlwaysRefreshToken(boolean alwaysRefreshToken) {
|
||||
this.alwaysRefreshToken = alwaysRefreshToken;
|
||||
}
|
||||
|
||||
public boolean isRegisterNodeAtStartup() {
|
||||
return registerNodeAtStartup;
|
||||
}
|
||||
|
||||
public void setRegisterNodeAtStartup(boolean registerNodeAtStartup) {
|
||||
this.registerNodeAtStartup = registerNodeAtStartup;
|
||||
}
|
||||
|
||||
public int getRegisterNodePeriod() {
|
||||
return registerNodePeriod;
|
||||
}
|
||||
|
||||
public void setRegisterNodePeriod(int registerNodePeriod) {
|
||||
this.registerNodePeriod = registerNodePeriod;
|
||||
}
|
||||
|
||||
public String getTokenStore() {
|
||||
return tokenStore;
|
||||
}
|
||||
|
||||
public void setTokenStore(String tokenStore) {
|
||||
this.tokenStore = tokenStore;
|
||||
}
|
||||
|
||||
public String getPrincipalAttribute() {
|
||||
return principalAttribute;
|
||||
}
|
||||
|
||||
public void setPrincipalAttribute(String principalAttribute) {
|
||||
this.principalAttribute = principalAttribute;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.keycloak.representations.idm;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
@@ -21,8 +22,11 @@ public class ApplicationRepresentation {
|
||||
protected Integer notBefore;
|
||||
protected Boolean bearerOnly;
|
||||
protected Boolean publicClient;
|
||||
protected String protocol;
|
||||
protected Map<String, String> attributes;
|
||||
protected Boolean fullScopeAllowed;
|
||||
|
||||
protected Integer nodeReRegistrationTimeout;
|
||||
protected Map<String, Integer> registeredNodes;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
@@ -143,4 +147,36 @@ public class ApplicationRepresentation {
|
||||
public void setFullScopeAllowed(Boolean fullScopeAllowed) {
|
||||
this.fullScopeAllowed = fullScopeAllowed;
|
||||
}
|
||||
|
||||
public String getProtocol() {
|
||||
return protocol;
|
||||
}
|
||||
|
||||
public void setProtocol(String protocol) {
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
public Map<String, String> getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public void setAttributes(Map<String, String> attributes) {
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
public Integer getNodeReRegistrationTimeout() {
|
||||
return nodeReRegistrationTimeout;
|
||||
}
|
||||
|
||||
public void setNodeReRegistrationTimeout(Integer nodeReRegistrationTimeout) {
|
||||
this.nodeReRegistrationTimeout = nodeReRegistrationTimeout;
|
||||
}
|
||||
|
||||
public Map<String, Integer> getRegisteredNodes() {
|
||||
return registeredNodes;
|
||||
}
|
||||
|
||||
public void setRegisteredNodes(Map<String, Integer> registeredNodes) {
|
||||
this.registeredNodes = registeredNodes;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.keycloak.representations.idm;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
@@ -16,6 +17,8 @@ public class OAuthClientRepresentation {
|
||||
protected ClaimRepresentation claims;
|
||||
protected Integer notBefore;
|
||||
protected Boolean publicClient;
|
||||
protected String protocol;
|
||||
protected Map<String, String> attributes;
|
||||
protected Boolean directGrantsOnly;
|
||||
protected Boolean fullScopeAllowed;
|
||||
|
||||
@@ -108,4 +111,19 @@ public class OAuthClientRepresentation {
|
||||
this.fullScopeAllowed = fullScopeAllowed;
|
||||
}
|
||||
|
||||
public String getProtocol() {
|
||||
return protocol;
|
||||
}
|
||||
|
||||
public void setProtocol(String protocol) {
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
public Map<String, String> getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public void setAttributes(Map<String, String> attributes) {
|
||||
this.attributes = attributes;
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,8 @@ public class RealmRepresentation {
|
||||
|
||||
protected String privateKey;
|
||||
protected String publicKey;
|
||||
protected String certificate;
|
||||
protected String codeSecret;
|
||||
protected RolesRepresentation roles;
|
||||
protected List<String> defaultRoles;
|
||||
protected Set<String> requiredCredentials;
|
||||
@@ -60,8 +62,8 @@ public class RealmRepresentation {
|
||||
protected String accountTheme;
|
||||
protected String adminTheme;
|
||||
protected String emailTheme;
|
||||
protected boolean eventsEnabled;
|
||||
protected long eventsExpiration;
|
||||
protected Boolean eventsEnabled;
|
||||
protected Long eventsExpiration;
|
||||
protected List<String> eventsListeners;
|
||||
|
||||
public String getId() {
|
||||
@@ -220,6 +222,22 @@ public class RealmRepresentation {
|
||||
this.publicKey = publicKey;
|
||||
}
|
||||
|
||||
public String getCertificate() {
|
||||
return certificate;
|
||||
}
|
||||
|
||||
public void setCertificate(String certificate) {
|
||||
this.certificate = certificate;
|
||||
}
|
||||
|
||||
public String getCodeSecret() {
|
||||
return codeSecret;
|
||||
}
|
||||
|
||||
public void setCodeSecret(String codeSecret) {
|
||||
this.codeSecret = codeSecret;
|
||||
}
|
||||
|
||||
public Boolean isPasswordCredentialGrantAllowed() {
|
||||
return passwordCredentialGrantAllowed;
|
||||
}
|
||||
@@ -436,7 +454,7 @@ public class RealmRepresentation {
|
||||
this.failureFactor = failureFactor;
|
||||
}
|
||||
|
||||
public boolean isEventsEnabled() {
|
||||
public Boolean isEventsEnabled() {
|
||||
return eventsEnabled;
|
||||
}
|
||||
|
||||
@@ -444,7 +462,7 @@ public class RealmRepresentation {
|
||||
this.eventsEnabled = eventsEnabled;
|
||||
}
|
||||
|
||||
public long getEventsExpiration() {
|
||||
public Long getEventsExpiration() {
|
||||
return eventsExpiration;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ public class UserSessionRepresentation {
|
||||
private String ipAddress;
|
||||
private long start;
|
||||
private long lastAccess;
|
||||
private Set<String> applications = new HashSet<String>();
|
||||
private Map<String, String> applications = new HashMap<String, String>();
|
||||
private Map<String, String> clients = new HashMap<String, String>();
|
||||
|
||||
public String getId() {
|
||||
@@ -58,11 +58,11 @@ public class UserSessionRepresentation {
|
||||
this.lastAccess = lastAccess;
|
||||
}
|
||||
|
||||
public Set<String> getApplications() {
|
||||
public Map<String, String> getApplications() {
|
||||
return applications;
|
||||
}
|
||||
|
||||
public void setApplications(Set<String> applications) {
|
||||
public void setApplications(Map<String, String> applications) {
|
||||
this.applications = applications;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package org.keycloak.util;
|
||||
|
||||
import org.bouncycastle.asn1.x509.X509Extensions;
|
||||
import org.bouncycastle.x509.X509V1CertificateGenerator;
|
||||
import org.bouncycastle.x509.X509V3CertificateGenerator;
|
||||
import org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure;
|
||||
import org.bouncycastle.x509.extension.SubjectKeyIdentifierStructure;
|
||||
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
import java.math.BigInteger;
|
||||
import java.security.KeyPair;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class CertificateUtils {
|
||||
public static X509Certificate generateV3Certificate(KeyPair keyPair, PrivateKey caPrivateKey, X509Certificate caCert, String subject) throws Exception {
|
||||
|
||||
X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
|
||||
X500Principal subjectName = new X500Principal("CN=" + subject);
|
||||
|
||||
BigInteger serialNumber = BigInteger.valueOf(System.currentTimeMillis());
|
||||
certGen.setSerialNumber(serialNumber);
|
||||
certGen.setIssuerDN(caCert.getSubjectX500Principal());
|
||||
certGen.setNotBefore(new Date(System.currentTimeMillis() - 100000));
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.add(Calendar.YEAR, 10);
|
||||
certGen.setNotAfter(calendar.getTime());
|
||||
certGen.setSubjectDN(subjectName);
|
||||
certGen.setPublicKey(keyPair.getPublic());
|
||||
certGen.setSignatureAlgorithm("SHA256WithRSAEncryption");
|
||||
|
||||
certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false,
|
||||
new AuthorityKeyIdentifierStructure(caCert));
|
||||
certGen.addExtension(X509Extensions.SubjectKeyIdentifier, false,
|
||||
new SubjectKeyIdentifierStructure(keyPair.getPublic()));
|
||||
|
||||
X509Certificate cert = certGen.generate(caPrivateKey, "BC"); // note: private key of CA
|
||||
return cert;
|
||||
}
|
||||
|
||||
public static X509Certificate generateV1SelfSignedCertificate(KeyPair keyPair, String subject) throws Exception {
|
||||
BigInteger serialNumber = BigInteger.valueOf(System.currentTimeMillis());
|
||||
X509V1CertificateGenerator certGen = new X509V1CertificateGenerator();
|
||||
X500Principal subjectPrincipal = new X500Principal("CN=" + subject);
|
||||
certGen.setSerialNumber(serialNumber);
|
||||
certGen.setIssuerDN(subjectPrincipal);
|
||||
certGen.setNotBefore(new Date(System.currentTimeMillis() - 100000));
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.add(Calendar.YEAR, 10);
|
||||
certGen.setNotAfter(calendar.getTime());
|
||||
certGen.setSubjectDN(subjectPrincipal);
|
||||
certGen.setPublicKey(keyPair.getPublic());
|
||||
certGen.setSignatureAlgorithm("SHA256WithRSAEncryption");
|
||||
X509Certificate cert = certGen.generate(keyPair.getPrivate(), "BC");
|
||||
return cert;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package org.keycloak.util;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class HostUtils {
|
||||
|
||||
public static String getHostName() {
|
||||
String jbossHostName = System.getProperty("jboss.host.name");
|
||||
if (jbossHostName != null) {
|
||||
return jbossHostName;
|
||||
} else {
|
||||
try {
|
||||
return InetAddress.getLocalHost().getHostName();
|
||||
} catch (UnknownHostException uhe) {
|
||||
throw new IllegalStateException(uhe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String getIpAddress() {
|
||||
try {
|
||||
String jbossHostName = System.getProperty("jboss.host.name");
|
||||
if (jbossHostName != null) {
|
||||
return InetAddress.getByName(jbossHostName).getHostAddress();
|
||||
} else {
|
||||
return java.net.InetAddress.getLocalHost().getHostAddress();
|
||||
}
|
||||
} catch (UnknownHostException uhe) {
|
||||
throw new IllegalStateException(uhe);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ import java.io.OutputStream;
|
||||
public class JsonSerialization {
|
||||
public static final ObjectMapper mapper = new ObjectMapper();
|
||||
public static final ObjectMapper prettyMapper = new ObjectMapper();
|
||||
public static final ObjectMapper sysPropertiesAwareMapper = new ObjectMapper(new SystemPropertiesJsonParserFactory());
|
||||
|
||||
static {
|
||||
mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
|
||||
@@ -46,7 +47,15 @@ public class JsonSerialization {
|
||||
}
|
||||
|
||||
public static <T> T readValue(InputStream bytes, Class<T> type) throws IOException {
|
||||
return mapper.readValue(bytes, type);
|
||||
return readValue(bytes, type, false);
|
||||
}
|
||||
|
||||
public static <T> T readValue(InputStream bytes, Class<T> type, boolean replaceSystemProperties) throws IOException {
|
||||
if (replaceSystemProperties) {
|
||||
return sysPropertiesAwareMapper.readValue(bytes, type);
|
||||
} else {
|
||||
return mapper.readValue(bytes, type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -18,4 +18,5 @@ public class KeystoreUtil {
|
||||
trustStream.close();
|
||||
return trustStore;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package org.keycloak.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
|
||||
import org.codehaus.jackson.JsonParser;
|
||||
import org.codehaus.jackson.io.IOContext;
|
||||
import org.codehaus.jackson.map.MappingJsonFactory;
|
||||
import org.codehaus.jackson.util.JsonParserDelegate;
|
||||
|
||||
/**
|
||||
* Provides replacing of system properties for parsed values
|
||||
*
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class SystemPropertiesJsonParserFactory extends MappingJsonFactory {
|
||||
|
||||
@Override
|
||||
protected JsonParser _createJsonParser(byte[] data, int offset, int len, IOContext ctxt) throws IOException {
|
||||
JsonParser delegate = super._createJsonParser(data, offset, len, ctxt);
|
||||
return new SystemPropertiesAwareJsonParser(delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonParser _createJsonParser(Reader r, IOContext ctxt) throws IOException {
|
||||
JsonParser delegate = super._createJsonParser(r, ctxt);
|
||||
return new SystemPropertiesAwareJsonParser(delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonParser _createJsonParser(InputStream in, IOContext ctxt) throws IOException {
|
||||
JsonParser delegate = super._createJsonParser(in, ctxt);
|
||||
return new SystemPropertiesAwareJsonParser(delegate);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static class SystemPropertiesAwareJsonParser extends JsonParserDelegate {
|
||||
|
||||
public SystemPropertiesAwareJsonParser(JsonParser d) {
|
||||
super(d);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() throws IOException {
|
||||
String orig = super.getText();
|
||||
return StringPropertyReplacer.replaceProperties(orig);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,12 +7,18 @@ import java.util.Date;
|
||||
*/
|
||||
public class Time {
|
||||
|
||||
private static int offset;
|
||||
|
||||
public static int currentTime() {
|
||||
return (int) (System.currentTimeMillis() / 1000);
|
||||
return ((int) (System.currentTimeMillis() / 1000)) + offset;
|
||||
}
|
||||
|
||||
public static Date toDate(int time) {
|
||||
return new Date(((long) time ) * 1000);
|
||||
}
|
||||
|
||||
public static void setOffset(int offset) {
|
||||
Time.offset = offset;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import java.util.regex.Pattern;
|
||||
*/
|
||||
public class UriUtils {
|
||||
|
||||
private static final Pattern originPattern = Pattern.compile("(http://|https://)[\\w]+(\\.[\\w]+)*(:[\\d]{2,5})?");
|
||||
private static final Pattern originPattern = Pattern.compile("(http://|https://)[\\w-]+(\\.[\\w-]+)*(:[\\d]{2,5})?");
|
||||
|
||||
public static String getOrigin(URI uri) {
|
||||
return getOrigin(uri.toString());
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.keycloak;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.representations.adapters.config.AdapterConfig;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class JsonParserTest {
|
||||
|
||||
@Test
|
||||
public void testParsingSystemProps() throws IOException {
|
||||
System.setProperty("my.host", "foo");
|
||||
System.setProperty("con.pool.size", "200");
|
||||
System.setProperty("allow.any.hostname", "true");
|
||||
|
||||
InputStream is = getClass().getClassLoader().getResourceAsStream("keycloak.json");
|
||||
|
||||
AdapterConfig config = JsonSerialization.readValue(is, AdapterConfig.class, true);
|
||||
Assert.assertEquals("http://foo:8080/auth", config.getAuthServerUrl());
|
||||
Assert.assertEquals("external", config.getSslRequired());
|
||||
Assert.assertEquals("angular-product${non.existing}", config.getResource());
|
||||
Assert.assertTrue(config.isPublicClient());
|
||||
Assert.assertTrue(config.isAllowAnyHostname());
|
||||
Assert.assertEquals(100, config.getCorsMaxAge());
|
||||
Assert.assertEquals(200, config.getConnectionPoolSize());
|
||||
}
|
||||
}
|
||||
@@ -72,7 +72,7 @@ public class RSAVerifierTest {
|
||||
|
||||
token = new AccessToken();
|
||||
token.subject("CN=Client")
|
||||
.audience("domain")
|
||||
.issuer("domain")
|
||||
.addAccess("service").addRole("admin");
|
||||
}
|
||||
|
||||
@@ -213,7 +213,7 @@ public class RSAVerifierTest {
|
||||
public void testTokenAuth() throws Exception {
|
||||
token = new AccessToken();
|
||||
token.subject("CN=Client")
|
||||
.audience("domain")
|
||||
.issuer("domain")
|
||||
.addAccess("service").addRole("admin").verifyCaller(true);
|
||||
|
||||
String encoded = new JWSBuilder()
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
package org.keycloak;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.jose.jws.JWSBuilder;
|
||||
import org.keycloak.jose.jws.JWSInput;
|
||||
import org.keycloak.jose.jws.crypto.RSAProvider;
|
||||
import org.keycloak.representations.AccessToken;
|
||||
import org.keycloak.representations.IDToken;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
|
||||
@@ -18,10 +23,7 @@ import java.security.KeyPairGenerator;
|
||||
public class SkeletonKeyTokenTest {
|
||||
@Test
|
||||
public void testToken() throws Exception {
|
||||
AccessToken token = new AccessToken();
|
||||
token.id("111");
|
||||
token.addAccess("foo").addRole("admin");
|
||||
token.addAccess("bar").addRole("user");
|
||||
AccessToken token = createSimpleToken();
|
||||
|
||||
String json = JsonSerialization.writeValueAsString(token);
|
||||
token = JsonSerialization.readValue(json, AccessToken.class);
|
||||
@@ -34,7 +36,7 @@ public class SkeletonKeyTokenTest {
|
||||
|
||||
@Test
|
||||
public void testRSA() throws Exception {
|
||||
AccessToken token = new AccessToken();
|
||||
AccessToken token = createSimpleToken();
|
||||
token.id("111");
|
||||
token.addAccess("foo").addRole("admin");
|
||||
token.addAccess("bar").addRole("user");
|
||||
@@ -51,4 +53,59 @@ public class SkeletonKeyTokenTest {
|
||||
Assert.assertEquals("111", token.getId());
|
||||
Assert.assertTrue(RSAProvider.verify(input, keyPair.getPublic()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerialization() throws Exception {
|
||||
AccessToken token = createSimpleToken();
|
||||
IDToken idToken = new IDToken();
|
||||
idToken.setEmail("joe@email.cz");
|
||||
|
||||
KeyPair keyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
|
||||
|
||||
String encoded = new JWSBuilder()
|
||||
.jsonContent(token)
|
||||
.rsa256(keyPair.getPrivate());
|
||||
String encodedIdToken = new JWSBuilder()
|
||||
.jsonContent(idToken)
|
||||
.rsa256(keyPair.getPrivate());
|
||||
|
||||
KeycloakSecurityContext ctx = new KeycloakSecurityContext(encoded, token, encodedIdToken, idToken);
|
||||
KeycloakPrincipal principal = new KeycloakPrincipal("joe", ctx);
|
||||
|
||||
// Serialize
|
||||
ByteArrayOutputStream bso = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(bso);
|
||||
oos.writeObject(principal);
|
||||
oos.close();
|
||||
|
||||
// Deserialize
|
||||
byte[] bytes = bso.toByteArray();
|
||||
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
|
||||
ObjectInputStream ois = new ObjectInputStream(bis);
|
||||
principal = (KeycloakPrincipal)ois.readObject();
|
||||
ctx = principal.getKeycloakSecurityContext();
|
||||
token = ctx.getToken();
|
||||
idToken = ctx.getIdToken();
|
||||
|
||||
System.out.println("Size of serialized principal: " + bytes.length);
|
||||
|
||||
Assert.assertEquals(encoded, ctx.getTokenString());
|
||||
Assert.assertEquals(encodedIdToken, ctx.getIdTokenString());
|
||||
Assert.assertEquals("111", token.getId());
|
||||
Assert.assertEquals("111", token.getId());
|
||||
Assert.assertTrue(token.getResourceAccess("foo").isUserInRole("admin"));
|
||||
Assert.assertTrue(token.getResourceAccess("bar").isUserInRole("user"));
|
||||
Assert.assertEquals("joe@email.cz", idToken.getEmail());
|
||||
Assert.assertEquals("acme", ctx.getRealm());
|
||||
ois.close();
|
||||
}
|
||||
|
||||
private AccessToken createSimpleToken() {
|
||||
AccessToken token = new AccessToken();
|
||||
token.id("111");
|
||||
token.issuer("acme");
|
||||
token.addAccess("foo").addRole("admin");
|
||||
token.addAccess("bar").addRole("user");
|
||||
return token;
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,8 @@ public class UriUtilsTest {
|
||||
assertValid("http://192.168.123.123");
|
||||
assertValid("https://192.168.123.123");
|
||||
assertValid("https://192.168.123.123:8080");
|
||||
assertValid("https://sub-sub.test.com");
|
||||
assertValid("https://sub.test-test.com");
|
||||
|
||||
assertInvalid("https://test/");
|
||||
assertInvalid("{");
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"auth-server-url" : "http://${my.host}:8080/auth",
|
||||
"ssl-required" : "external",
|
||||
"resource" : "angular-product${non.existing}",
|
||||
"public-client" : true,
|
||||
"allow-any-hostname": "${allow.any.hostname}",
|
||||
"cors-max-age": 100,
|
||||
"connection-pool-size": "${con.pool.size}"
|
||||
}
|
||||
Vendored
+1
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.0.3.Final</version>
|
||||
<version>1.1.0.Beta1</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
Vendored
+43
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.0.3.Final</version>
|
||||
<version>1.1.0.Beta1</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@@ -26,6 +26,16 @@
|
||||
<artifactId>keycloak-connections-jpa</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-connections-jpa-liquibase</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-connections-infinispan</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-model-jpa</artifactId>
|
||||
@@ -46,6 +56,16 @@
|
||||
<artifactId>keycloak-model-sessions-mongo</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-model-sessions-infinispan</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-invalidation-cache-infinispan</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-events-jpa</artifactId>
|
||||
@@ -123,6 +143,17 @@
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- saml -->
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-saml-protocol</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.picketlink</groupId>
|
||||
<artifactId>picketlink-federation</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- mongo -->
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
@@ -154,6 +185,17 @@
|
||||
<groupId>de.idyl</groupId>
|
||||
<artifactId>winzipaes</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.liquibase</groupId>
|
||||
<artifactId>liquibase-core</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
Vendored
+1
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.0.3.Final</version>
|
||||
<version>1.1.0.Beta1</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
<excludes>
|
||||
<exclude>**/*.sh</exclude>
|
||||
<exclude>welcome-content/*</exclude>
|
||||
<exclude>**/modules/system/layers/base/org/picketlink/**</exclude>
|
||||
</excludes>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
@@ -31,6 +32,13 @@
|
||||
</includes>
|
||||
<fileMode>0755</fileMode>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>${project.build.directory}/unpacked/modules</directory>
|
||||
<outputDirectory>keycloak/modules/system/layers/base</outputDirectory>
|
||||
<includes>
|
||||
<include>org/picketlink/**</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>${project.build.directory}/unpacked/deployments</directory>
|
||||
<outputDirectory>keycloak/standalone/deployments</outputDirectory>
|
||||
@@ -77,6 +85,7 @@
|
||||
<include>org.keycloak:keycloak-wildfly-adapter-dist:zip</include>
|
||||
<include>org.keycloak:keycloak-as7-adapter-dist:zip</include>
|
||||
<include>org.keycloak:keycloak-eap6-adapter-dist:zip</include>
|
||||
<include>org.keycloak:keycloak-tomcat7-adapter-dist:zip</include>
|
||||
</includes>
|
||||
<outputDirectory>adapters</outputDirectory>
|
||||
</dependencySet>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.0.3.Final</version>
|
||||
<version>1.1.0.Beta1</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -26,6 +26,12 @@
|
||||
<version>${project.version}</version>
|
||||
<type>zip</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-tomcat7-adapter-dist</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>zip</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-eap6-adapter-dist</artifactId>
|
||||
@@ -90,6 +96,13 @@
|
||||
<outputDirectory>${project.build.directory}/unpacked/js-adapter</outputDirectory>
|
||||
<includes>*.js</includes>
|
||||
</artifactItem>
|
||||
<artifactItem>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-jboss-modules</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>zip</type>
|
||||
<outputDirectory>${project.build.directory}/unpacked/modules</outputDirectory>
|
||||
</artifactItem>
|
||||
</artifactItems>
|
||||
<excludes>**/welcome-content/*</excludes>
|
||||
</configuration>
|
||||
|
||||
@@ -46,6 +46,11 @@
|
||||
<login-module code="org.keycloak.adapters.jboss.KeycloakLoginModule" flag="required"/>
|
||||
</authentication>
|
||||
</security-domain>
|
||||
<security-domain name="sp" cache-type="default">
|
||||
<authentication>
|
||||
<login-module code="org.picketlink.identity.federation.bindings.wildfly.SAML2LoginModule" flag="required"/>
|
||||
</authentication>
|
||||
</security-domain>
|
||||
</xsl:copy>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<fileSet>
|
||||
<directory>${project.build.directory}/unpacked</directory>
|
||||
<excludes>
|
||||
<exclude>org/picketlink/**</exclude>
|
||||
<exclude>org/keycloak/keycloak-undertow-adapter/**</exclude>
|
||||
<exclude>org/keycloak/keycloak-wildfly-subsystem/**</exclude>
|
||||
<exclude>org/keycloak/keycloak-wildfly-adapter/**</exclude>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.0.3.Final</version>
|
||||
<version>1.1.0.Beta1</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -10,8 +10,10 @@
|
||||
<fileSet>
|
||||
<directory>${project.build.directory}/unpacked</directory>
|
||||
<excludes>
|
||||
<exclude>org/picketlink/**</exclude>
|
||||
<exclude>org/keycloak/keycloak-undertow-adapter/**</exclude>
|
||||
<exclude>org/keycloak/keycloak-wildfly-subsystem/**</exclude>
|
||||
<exclude>org/keycloak/keycloak-wildfly-adapter/**</exclude>
|
||||
</excludes>
|
||||
<outputDirectory>modules/system/layers/base</outputDirectory>
|
||||
</fileSet>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.0.3.Final</version>
|
||||
<version>1.1.0.Beta1</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -26,6 +26,14 @@
|
||||
<exclude name="**/subsystem-config.xml"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
<copy todir="target/examples/saml" overwrite="true">
|
||||
<fileset dir="../../examples/saml">
|
||||
<exclude name="**/target/**"/>
|
||||
<exclude name="**/*.iml"/>
|
||||
<exclude name="**/*.unconfigured"/>
|
||||
<exclude name="**/subsystem-config.xml"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
<copy todir="target/examples/js-console" overwrite="true">
|
||||
<fileset dir="../../examples/js-console">
|
||||
<exclude name="**/target/**"/>
|
||||
@@ -34,6 +42,22 @@
|
||||
<exclude name="**/subsystem-config.xml"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
<copy todir="target/examples/multi-tenant" overwrite="true">
|
||||
<fileset dir="../../examples/multi-tenant">
|
||||
<exclude name="**/target/**"/>
|
||||
<exclude name="**/*.iml"/>
|
||||
<exclude name="**/*.unconfigured"/>
|
||||
<exclude name="**/subsystem-config.xml"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
<copy todir="target/examples/admin-client" overwrite="true">
|
||||
<fileset dir="../../examples/admin-client">
|
||||
<exclude name="**/target/**"/>
|
||||
<exclude name="**/*.iml"/>
|
||||
<exclude name="**/*.unconfigured"/>
|
||||
<exclude name="**/subsystem-config.xml"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
<copy todir="target/examples/themes" overwrite="true">
|
||||
<fileset dir="../../examples/themes">
|
||||
<exclude name="**/target/**"/>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.0.3.Final</version>
|
||||
<version>1.1.0.Beta1</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -81,6 +81,35 @@
|
||||
<module-def name="org.keycloak.keycloak-as7-subsystem">
|
||||
<maven-resource group="org.keycloak" artifact="keycloak-as7-subsystem"/>
|
||||
</module-def>
|
||||
<module-def name="org.picketlink">
|
||||
</module-def>
|
||||
<module-def name="org.picketlink.common">
|
||||
<maven-resource group="org.picketlink" artifact="picketlink-common"/>
|
||||
</module-def>
|
||||
<module-def name="org.picketlink.config">
|
||||
<maven-resource group="org.picketlink" artifact="picketlink-config"/>
|
||||
</module-def>
|
||||
<module-def name="org.picketlink.core">
|
||||
<maven-resource group="org.picketlink" artifact="picketlink-impl"/>
|
||||
</module-def>
|
||||
<module-def name="org.picketlink.core.api">
|
||||
<maven-resource group="org.picketlink" artifact="picketlink-api"/>
|
||||
</module-def>
|
||||
<module-def name="org.picketlink.federation">
|
||||
<maven-resource group="org.picketlink" artifact="picketlink-federation"/>
|
||||
</module-def>
|
||||
<module-def name="org.picketlink.federation.bindings">
|
||||
<maven-resource group="org.picketlink" artifact="picketlink-wildlfy-common"/>
|
||||
</module-def>
|
||||
<module-def name="org.picketlink.idm">
|
||||
<maven-resource group="org.picketlink" artifact="picketlink-idm-impl"/>
|
||||
</module-def>
|
||||
<module-def name="org.picketlink.idm.api">
|
||||
<maven-resource group="org.picketlink" artifact="picketlink-idm-api"/>
|
||||
</module-def>
|
||||
<module-def name="org.picketlink.idm.schema">
|
||||
<maven-resource group="org.picketlink" artifact="picketlink-idm-simple-schema"/>
|
||||
</module-def>
|
||||
</target>
|
||||
|
||||
<target name="clean-target">
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.0.3.Final</version>
|
||||
<version>1.1.0.Beta1</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -83,6 +83,42 @@
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk16</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.picketlink</groupId>
|
||||
<artifactId>picketlink-common</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.picketlink</groupId>
|
||||
<artifactId>picketlink-idm-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.picketlink</groupId>
|
||||
<artifactId>picketlink-idm-impl</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.picketlink</groupId>
|
||||
<artifactId>picketlink-federation</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.picketlink</groupId>
|
||||
<artifactId>picketlink-wildlfy-common</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.picketlink</groupId>
|
||||
<artifactId>picketlink-idm-simple-schema</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.picketlink</groupId>
|
||||
<artifactId>picketlink-config</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.picketlink</groupId>
|
||||
<artifactId>picketlink-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.picketlink</groupId>
|
||||
<artifactId>picketlink-impl</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!-- ~ JBoss, Home of Professional Open Source. ~ Copyright 2012, Red Hat,
|
||||
Inc., and individual contributors ~ as indicated by the @author tags. See
|
||||
the copyright.txt file in the ~ distribution for a full listing of individual
|
||||
contributors. ~ ~ This is free software; you can redistribute it and/or modify
|
||||
it ~ under the terms of the GNU Lesser General Public License as ~ published
|
||||
by the Free Software Foundation; either version 2.1 of ~ the License, or
|
||||
(at your option) any later version. ~ ~ This software is distributed in the
|
||||
hope that it will be useful, ~ but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU ~ Lesser General Public License for more details. ~ ~ You should
|
||||
have received a copy of the GNU Lesser General Public ~ License along with
|
||||
this software; if not, write to the Free ~ Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA ~ 02110-1301 USA, or see the FSF site:
|
||||
http://www.fsf.org. -->
|
||||
|
||||
<module xmlns="urn:jboss:module:1.1" name="org.picketlink.common">
|
||||
|
||||
<resources>
|
||||
<!-- Insert resources here -->
|
||||
</resources>
|
||||
|
||||
<dependencies>
|
||||
<module name="javax.api"/>
|
||||
<module name="javax.xml.stream.api"/>
|
||||
<module name="org.jboss.logging"/>
|
||||
</dependencies>
|
||||
|
||||
</module>
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!-- ~ JBoss, Home of Professional Open Source. ~ Copyright 2012, Red Hat,
|
||||
Inc., and individual contributors ~ as indicated by the @author tags. See
|
||||
the copyright.txt file in the ~ distribution for a full listing of individual
|
||||
contributors. ~ ~ This is free software; you can redistribute it and/or modify
|
||||
it ~ under the terms of the GNU Lesser General Public License as ~ published
|
||||
by the Free Software Foundation; either version 2.1 of ~ the License, or
|
||||
(at your option) any later version. ~ ~ This software is distributed in the
|
||||
hope that it will be useful, ~ but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU ~ Lesser General Public License for more details. ~ ~ You should
|
||||
have received a copy of the GNU Lesser General Public ~ License along with
|
||||
this software; if not, write to the Free ~ Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA ~ 02110-1301 USA, or see the FSF site:
|
||||
http://www.fsf.org. -->
|
||||
|
||||
<module xmlns="urn:jboss:module:1.1" name="org.picketlink.config">
|
||||
<resources>
|
||||
<!-- Insert resources here -->
|
||||
</resources>
|
||||
|
||||
<dependencies>
|
||||
<module name="javax.api"/>
|
||||
<module name="org.picketlink.common"/>
|
||||
</dependencies>
|
||||
|
||||
</module>
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!-- ~ JBoss, Home of Professional Open Source. ~ Copyright 2012, Red Hat,
|
||||
Inc., and individual contributors ~ as indicated by the @author tags. See
|
||||
the copyright.txt file in the ~ distribution for a full listing of individual
|
||||
contributors. ~ ~ This is free software; you can redistribute it and/or modify
|
||||
it ~ under the terms of the GNU Lesser General Public License as ~ published
|
||||
by the Free Software Foundation; either version 2.1 of ~ the License, or
|
||||
(at your option) any later version. ~ ~ This software is distributed in the
|
||||
hope that it will be useful, ~ but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU ~ Lesser General Public License for more details. ~ ~ You should
|
||||
have received a copy of the GNU Lesser General Public ~ License along with
|
||||
this software; if not, write to the Free ~ Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA ~ 02110-1301 USA, or see the FSF site:
|
||||
http://www.fsf.org. -->
|
||||
|
||||
<module xmlns="urn:jboss:module:1.1" name="org.picketlink.core.api">
|
||||
<resources>
|
||||
<!-- Insert resources here -->
|
||||
</resources>
|
||||
|
||||
<dependencies>
|
||||
<module name="javax.enterprise.api" />
|
||||
<module name="javax.inject.api" />
|
||||
<module name="javax.servlet.api" optional="true" />
|
||||
<module name="javax.persistence.api" optional="true" />
|
||||
<module name="org.picketlink.common" />
|
||||
<module name="org.jboss.logging"/>
|
||||
<module name="org.picketlink.idm.api" export="true" />
|
||||
</dependencies>
|
||||
</module>
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!-- ~ JBoss, Home of Professional Open Source. ~ Copyright 2012, Red Hat,
|
||||
Inc., and individual contributors ~ as indicated by the @author tags. See
|
||||
the copyright.txt file in the ~ distribution for a full listing of individual
|
||||
contributors. ~ ~ This is free software; you can redistribute it and/or modify
|
||||
it ~ under the terms of the GNU Lesser General Public License as ~ published
|
||||
by the Free Software Foundation; either version 2.1 of ~ the License, or
|
||||
(at your option) any later version. ~ ~ This software is distributed in the
|
||||
hope that it will be useful, ~ but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU ~ Lesser General Public License for more details. ~ ~ You should
|
||||
have received a copy of the GNU Lesser General Public ~ License along with
|
||||
this software; if not, write to the Free ~ Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA ~ 02110-1301 USA, or see the FSF site:
|
||||
http://www.fsf.org. -->
|
||||
|
||||
<module xmlns="urn:jboss:module:1.1" name="org.picketlink.core">
|
||||
<resources>
|
||||
<!-- Insert resources here -->
|
||||
</resources>
|
||||
|
||||
<dependencies>
|
||||
<module name="javax.enterprise.api" />
|
||||
<module name="javax.inject.api" />
|
||||
<module name="javax.servlet.api" optional="true" />
|
||||
<module name="javax.persistence.api" optional="true" />
|
||||
<module name="org.picketlink.common" />
|
||||
<module name="org.jboss.logging"/>
|
||||
<module name="org.picketlink.core.api" export="true" />
|
||||
<module name="org.picketlink.idm.api" export="true" />
|
||||
<module name="org.picketlink.idm" />
|
||||
</dependencies>
|
||||
</module>
|
||||
Executable
+53
@@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!-- ~ JBoss, Home of Professional Open Source. ~ Copyright 2012, Red Hat,
|
||||
Inc., and individual contributors ~ as indicated by the @author tags. See
|
||||
the copyright.txt file in the ~ distribution for a full listing of individual
|
||||
contributors. ~ ~ This is free software; you can redistribute it and/or modify
|
||||
it ~ under the terms of the GNU Lesser General Public License as ~ published
|
||||
by the Free Software Foundation; either version 2.1 of ~ the License, or
|
||||
(at your option) any later version. ~ ~ This software is distributed in the
|
||||
hope that it will be useful, ~ but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU ~ Lesser General Public License for more details. ~ ~ You should
|
||||
have received a copy of the GNU Lesser General Public ~ License along with
|
||||
this software; if not, write to the Free ~ Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA ~ 02110-1301 USA, or see the FSF site:
|
||||
http://www.fsf.org. -->
|
||||
|
||||
<module xmlns="urn:jboss:module:1.1" name="org.picketlink.federation.bindings">
|
||||
<resources>
|
||||
<!-- Insert resources here -->
|
||||
</resources>
|
||||
|
||||
<dependencies>
|
||||
<module name="javax.security.auth.message.api" />
|
||||
<module name="javax.security.jacc.api" />
|
||||
<module name="javax.transaction.api" />
|
||||
<module name="javax.xml.bind.api" />
|
||||
<module name="javax.xml.stream.api" />
|
||||
<module name="javax.servlet.api" />
|
||||
<module name="org.jboss.common-core" />
|
||||
<module name="org.jboss.logging" />
|
||||
<module name="org.wildfly.extension.undertow" />
|
||||
<module name="org.jboss.security.xacml" />
|
||||
<module name="org.picketbox" />
|
||||
<module name="javax.xml.ws.api" />
|
||||
<module name="org.apache.log4j" />
|
||||
<module name="org.apache.santuario.xmlsec">
|
||||
<imports>
|
||||
<exclude path="javax/*"/>
|
||||
</imports>
|
||||
</module>
|
||||
<module name="javax.api" />
|
||||
<module name="org.jboss.ws.api" />
|
||||
<module name="org.jboss.ws.spi" />
|
||||
<module name="org.apache.cxf" />
|
||||
<module name="io.undertow.core" />
|
||||
<module name="io.undertow.servlet" />
|
||||
<module name="org.picketlink.common" />
|
||||
<module name="org.picketlink.config" />
|
||||
<module name="org.picketlink.federation" />
|
||||
</dependencies>
|
||||
|
||||
</module>
|
||||
Executable
+56
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!-- ~ JBoss, Home of Professional Open Source. ~ Copyright 2012, Red Hat,
|
||||
Inc., and individual contributors ~ as indicated by the @author tags. See
|
||||
the copyright.txt file in the ~ distribution for a full listing of individual
|
||||
contributors. ~ ~ This is free software; you can redistribute it and/or modify
|
||||
it ~ under the terms of the GNU Lesser General Public License as ~ published
|
||||
by the Free Software Foundation; either version 2.1 of ~ the License, or
|
||||
(at your option) any later version. ~ ~ This software is distributed in the
|
||||
hope that it will be useful, ~ but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU ~ Lesser General Public License for more details. ~ ~ You should
|
||||
have received a copy of the GNU Lesser General Public ~ License along with
|
||||
this software; if not, write to the Free ~ Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA ~ 02110-1301 USA, or see the FSF site:
|
||||
http://www.fsf.org. -->
|
||||
|
||||
<module xmlns="urn:jboss:module:1.1" name="org.picketlink.federation">
|
||||
<resources>
|
||||
<!-- Insert resources here -->
|
||||
</resources>
|
||||
|
||||
<dependencies>
|
||||
<module name="javax.security.auth.message.api" />
|
||||
<module name="javax.security.jacc.api" />
|
||||
<module name="javax.transaction.api" />
|
||||
<module name="javax.xml.bind.api" />
|
||||
<module name="javax.xml.stream.api" />
|
||||
<module name="javax.servlet.api" />
|
||||
<module name="org.jboss.common-core" />
|
||||
<module name="org.jboss.logging" />
|
||||
<module name="org.jboss.as.web-common" />
|
||||
<module name="org.jboss.security.xacml" />
|
||||
<module name="org.picketbox" />
|
||||
<module name="javax.xml.ws.api" />
|
||||
<module name="org.apache.log4j" />
|
||||
<module name="org.apache.santuario.xmlsec">
|
||||
<imports>
|
||||
<exclude path="javax/*"/>
|
||||
</imports>
|
||||
</module>
|
||||
<module name="javax.api" />
|
||||
<module name="org.jboss.ws.api" />
|
||||
<module name="org.jboss.ws.spi" />
|
||||
<module name="org.apache.cxf" />
|
||||
<module name="org.picketlink.common" />
|
||||
<module name="org.picketlink.config">
|
||||
<imports>
|
||||
<exclude-set>
|
||||
<path name="org.picketlink.config.idm" />
|
||||
</exclude-set>
|
||||
</imports>
|
||||
</module>
|
||||
</dependencies>
|
||||
|
||||
</module>
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!-- ~ JBoss, Home of Professional Open Source. ~ Copyright 2012, Red Hat,
|
||||
Inc., and individual contributors ~ as indicated by the @author tags. See
|
||||
the copyright.txt file in the ~ distribution for a full listing of individual
|
||||
contributors. ~ ~ This is free software; you can redistribute it and/or modify
|
||||
it ~ under the terms of the GNU Lesser General Public License as ~ published
|
||||
by the Free Software Foundation; either version 2.1 of ~ the License, or
|
||||
(at your option) any later version. ~ ~ This software is distributed in the
|
||||
hope that it will be useful, ~ but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU ~ Lesser General Public License for more details. ~ ~ You should
|
||||
have received a copy of the GNU Lesser General Public ~ License along with
|
||||
this software; if not, write to the Free ~ Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA ~ 02110-1301 USA, or see the FSF site:
|
||||
http://www.fsf.org. -->
|
||||
|
||||
<module xmlns="urn:jboss:module:1.1" name="org.picketlink.idm.api">
|
||||
|
||||
<resources>
|
||||
<!-- Insert resources here -->
|
||||
</resources>
|
||||
|
||||
<dependencies>
|
||||
<module name="javax.api"/>
|
||||
<module name="org.jboss.logging"/>
|
||||
<module name="org.picketlink.common"/>
|
||||
</dependencies>
|
||||
|
||||
</module>
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!-- ~ JBoss, Home of Professional Open Source. ~ Copyright 2012, Red Hat,
|
||||
Inc., and individual contributors ~ as indicated by the @author tags. See
|
||||
the copyright.txt file in the ~ distribution for a full listing of individual
|
||||
contributors. ~ ~ This is free software; you can redistribute it and/or modify
|
||||
it ~ under the terms of the GNU Lesser General Public License as ~ published
|
||||
by the Free Software Foundation; either version 2.1 of ~ the License, or
|
||||
(at your option) any later version. ~ ~ This software is distributed in the
|
||||
hope that it will be useful, ~ but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU ~ Lesser General Public License for more details. ~ ~ You should
|
||||
have received a copy of the GNU Lesser General Public ~ License along with
|
||||
this software; if not, write to the Free ~ Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA ~ 02110-1301 USA, or see the FSF site:
|
||||
http://www.fsf.org. -->
|
||||
|
||||
<module xmlns="urn:jboss:module:1.1" name="org.picketlink.idm">
|
||||
|
||||
<resources>
|
||||
<!-- Insert resources here -->
|
||||
</resources>
|
||||
|
||||
<dependencies>
|
||||
<module name="javax.api" />
|
||||
<module name="javax.persistence.api" />
|
||||
<module name="org.hibernate" optional="true" />
|
||||
<module name="org.javassist" optional="true" />
|
||||
<module name="org.jboss.logging" />
|
||||
<module name="org.picketlink.common" />
|
||||
<module name="org.picketlink.idm.api" export="true" />
|
||||
</dependencies>
|
||||
|
||||
</module>
|
||||
Executable
+32
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!-- ~ JBoss, Home of Professional Open Source. ~ Copyright 2012, Red Hat,
|
||||
Inc., and individual contributors ~ as indicated by the @author tags. See
|
||||
the copyright.txt file in the ~ distribution for a full listing of individual
|
||||
contributors. ~ ~ This is free software; you can redistribute it and/or modify
|
||||
it ~ under the terms of the GNU Lesser General Public License as ~ published
|
||||
by the Free Software Foundation; either version 2.1 of ~ the License, or
|
||||
(at your option) any later version. ~ ~ This software is distributed in the
|
||||
hope that it will be useful, ~ but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU ~ Lesser General Public License for more details. ~ ~ You should
|
||||
have received a copy of the GNU Lesser General Public ~ License along with
|
||||
this software; if not, write to the Free ~ Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA ~ 02110-1301 USA, or see the FSF site:
|
||||
http://www.fsf.org. -->
|
||||
|
||||
<module xmlns="urn:jboss:module:1.1" name="org.picketlink.idm.schema">
|
||||
|
||||
<resources>
|
||||
<!-- Insert resources here -->
|
||||
</resources>
|
||||
|
||||
<dependencies>
|
||||
<module name="javax.api"/>
|
||||
<module name="javax.persistence.api"/>
|
||||
<module name="org.hibernate" />
|
||||
<module name="org.javassist"/>
|
||||
<module name="org.picketlink.idm.api"/>
|
||||
</dependencies>
|
||||
|
||||
</module>
|
||||
Loaded 100 of 715 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user