commit
2b525c6016
3 changed files with 171 additions and 167 deletions
258
core/src/main/java/org/keycloak/Config.java
Normal file → Executable file
258
core/src/main/java/org/keycloak/Config.java
Normal file → Executable file
|
@ -1,129 +1,129 @@
|
|||
package org.keycloak;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class Config {
|
||||
|
||||
private static ConfigProvider configProvider = new SystemPropertiesConfigProvider();
|
||||
|
||||
public static void init(ConfigProvider configProvider) {
|
||||
Config.configProvider = configProvider;
|
||||
}
|
||||
|
||||
public static String getAdminRealm() {
|
||||
return configProvider.scope("admin").get("realm", "keycloak-admin");
|
||||
}
|
||||
|
||||
public static String getProvider(String spi) {
|
||||
return configProvider.getProvider(spi);
|
||||
}
|
||||
|
||||
public static Scope scope(String... scope) {
|
||||
return configProvider.scope(scope);
|
||||
}
|
||||
|
||||
public static interface ConfigProvider {
|
||||
|
||||
String getProvider(String spi);
|
||||
|
||||
Scope scope(String... scope);
|
||||
|
||||
}
|
||||
|
||||
public static class SystemPropertiesConfigProvider implements ConfigProvider {
|
||||
|
||||
@Override
|
||||
public String getProvider(String spi) {
|
||||
return System.getProperties().getProperty("keycloak." + spi + ".provider");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Scope scope(String... scope) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("keycloak.");
|
||||
for (String s : scope) {
|
||||
sb.append(s);
|
||||
sb.append(".");
|
||||
}
|
||||
return new SystemPropertiesScope(sb.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class SystemPropertiesScope implements Scope {
|
||||
|
||||
private String prefix;
|
||||
|
||||
public SystemPropertiesScope(String prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String get(String key) {
|
||||
return get(key, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String get(String key, String defaultValue) {
|
||||
return System.getProperty(prefix + key, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getInt(String key) {
|
||||
return getInt(key, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getInt(String key, Integer defaultValue) {
|
||||
String v = get(key, null);
|
||||
return v != null ? Integer.parseInt(v) : defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getLong(String key) {
|
||||
return getLong(key, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getLong(String key, Long defaultValue) {
|
||||
String v = get(key, null);
|
||||
return v != null ? Long.parseLong(v) : defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getBoolean(String key) {
|
||||
return getBoolean(key, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getBoolean(String key, Boolean defaultValue) {
|
||||
String v = get(key, null);
|
||||
return v != null ? Boolean.parseBoolean(v) : defaultValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public static interface Scope {
|
||||
|
||||
String get(String key);
|
||||
|
||||
String get(String key, String defaultValue);
|
||||
|
||||
Integer getInt(String key);
|
||||
|
||||
Integer getInt(String key, Integer defaultValue);
|
||||
|
||||
Long getLong(String key);
|
||||
|
||||
Long getLong(String key, Long defaultValue);
|
||||
|
||||
Boolean getBoolean(String key);
|
||||
|
||||
Boolean getBoolean(String key, Boolean defaultValue);
|
||||
|
||||
}
|
||||
}
|
||||
package org.keycloak;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class Config {
|
||||
|
||||
private static ConfigProvider configProvider = new SystemPropertiesConfigProvider();
|
||||
|
||||
public static void init(ConfigProvider configProvider) {
|
||||
Config.configProvider = configProvider;
|
||||
}
|
||||
|
||||
public static String getAdminRealm() {
|
||||
return configProvider.scope("admin").get("realm", "keycloak-admin");
|
||||
}
|
||||
|
||||
public static String getProvider(String spi) {
|
||||
return configProvider.getProvider(spi);
|
||||
}
|
||||
|
||||
public static Scope scope(String... scope) {
|
||||
return configProvider.scope(scope);
|
||||
}
|
||||
|
||||
public static interface ConfigProvider {
|
||||
|
||||
String getProvider(String spi);
|
||||
|
||||
Scope scope(String... scope);
|
||||
|
||||
}
|
||||
|
||||
public static class SystemPropertiesConfigProvider implements ConfigProvider {
|
||||
|
||||
@Override
|
||||
public String getProvider(String spi) {
|
||||
return System.getProperties().getProperty("keycloak." + spi + ".provider");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Scope scope(String... scope) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("keycloak.");
|
||||
for (String s : scope) {
|
||||
sb.append(s);
|
||||
sb.append(".");
|
||||
}
|
||||
return new SystemPropertiesScope(sb.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class SystemPropertiesScope implements Scope {
|
||||
|
||||
private String prefix;
|
||||
|
||||
public SystemPropertiesScope(String prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String get(String key) {
|
||||
return get(key, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String get(String key, String defaultValue) {
|
||||
return System.getProperty(prefix + key, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getInt(String key) {
|
||||
return getInt(key, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getInt(String key, Integer defaultValue) {
|
||||
String v = get(key, null);
|
||||
return v != null ? Integer.parseInt(v) : defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getLong(String key) {
|
||||
return getLong(key, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getLong(String key, Long defaultValue) {
|
||||
String v = get(key, null);
|
||||
return v != null ? Long.parseLong(v) : defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getBoolean(String key) {
|
||||
return getBoolean(key, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getBoolean(String key, Boolean defaultValue) {
|
||||
String v = get(key, null);
|
||||
return v != null ? Boolean.parseBoolean(v) : defaultValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public static interface Scope {
|
||||
|
||||
String get(String key);
|
||||
|
||||
String get(String key, String defaultValue);
|
||||
|
||||
Integer getInt(String key);
|
||||
|
||||
Integer getInt(String key, Integer defaultValue);
|
||||
|
||||
Long getLong(String key);
|
||||
|
||||
Long getLong(String key, Long defaultValue);
|
||||
|
||||
Boolean getBoolean(String key);
|
||||
|
||||
Boolean getBoolean(String key, Boolean defaultValue);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,7 +143,7 @@ public class BruteForceProtector implements Runnable {
|
|||
run = false;
|
||||
try {
|
||||
queue.offer(new ShutdownEvent());
|
||||
shutdownLatch.await(5, TimeUnit.SECONDS);
|
||||
shutdownLatch.await(10, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
@ -152,46 +152,50 @@ public class BruteForceProtector implements Runnable {
|
|||
|
||||
public void run() {
|
||||
final ArrayList<LoginEvent> events = new ArrayList<LoginEvent>(TRANSACTION_SIZE + 1);
|
||||
while (run) {
|
||||
try {
|
||||
LoginEvent take = queue.poll(2, TimeUnit.SECONDS);
|
||||
if (take == null) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
while (run) {
|
||||
try {
|
||||
events.add(take);
|
||||
queue.drainTo(events, TRANSACTION_SIZE);
|
||||
Collections.sort(events); // we sort to avoid deadlock due to ordered updates. Maybe I'm overthinking this.
|
||||
ProviderSession providerSession = factory.createSession();
|
||||
KeycloakSession session = providerSession.getProvider(KeycloakSession.class);
|
||||
session.getTransaction().begin();
|
||||
try {
|
||||
for (LoginEvent event : events) {
|
||||
if (event instanceof FailedLogin) {
|
||||
failure(session, event);
|
||||
}
|
||||
}
|
||||
session.getTransaction().commit();
|
||||
} catch (Exception e) {
|
||||
session.getTransaction().rollback();
|
||||
throw e;
|
||||
} finally {
|
||||
for (LoginEvent event : events) {
|
||||
if (event instanceof FailedLogin) {
|
||||
((FailedLogin) event).latch.countDown();
|
||||
}
|
||||
}
|
||||
events.clear();
|
||||
providerSession.close();
|
||||
LoginEvent take = queue.poll(2, TimeUnit.SECONDS);
|
||||
if (take == null) {
|
||||
continue;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed processing event", e);
|
||||
try {
|
||||
events.add(take);
|
||||
queue.drainTo(events, TRANSACTION_SIZE);
|
||||
Collections.sort(events); // we sort to avoid deadlock due to ordered updates. Maybe I'm overthinking this.
|
||||
ProviderSession providerSession = factory.createSession();
|
||||
KeycloakSession session = providerSession.getProvider(KeycloakSession.class);
|
||||
session.getTransaction().begin();
|
||||
try {
|
||||
for (LoginEvent event : events) {
|
||||
if (event instanceof FailedLogin) {
|
||||
failure(session, event);
|
||||
} else if (event instanceof ShutdownEvent) {
|
||||
run = false;
|
||||
}
|
||||
}
|
||||
session.getTransaction().commit();
|
||||
} catch (Exception e) {
|
||||
session.getTransaction().rollback();
|
||||
throw e;
|
||||
} finally {
|
||||
for (LoginEvent event : events) {
|
||||
if (event instanceof FailedLogin) {
|
||||
((FailedLogin) event).latch.countDown();
|
||||
}
|
||||
}
|
||||
events.clear();
|
||||
providerSession.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed processing event", e);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
break;
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
break;
|
||||
} finally {
|
||||
shutdownLatch.countDown();
|
||||
}
|
||||
} finally {
|
||||
shutdownLatch.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ public class KeycloakApplication extends Application {
|
|||
}
|
||||
|
||||
public static void setupScheduledTasks(final ProviderSessionFactory providerSessionFactory) {
|
||||
long interval = Config.scope("scheduled").getLong("interval") * 1000;
|
||||
long interval = Config.scope("scheduled").getLong("interval", 60L) * 1000;
|
||||
|
||||
TimerProvider timer = providerSessionFactory.createSession().getProvider(TimerProvider.class);
|
||||
timer.schedule(new ScheduledTaskRunner(providerSessionFactory, new ClearExpiredAuditEvents()), interval);
|
||||
|
|
Loading…
Reference in a new issue