diff --git a/src/main/java/org/softwarefactory/keycloak/providers/events/http/HTTPEventListenerProvider.java b/src/main/java/org/softwarefactory/keycloak/providers/events/http/HTTPEventListenerProvider.java index 14b0cbb..0ef5b79 100755 --- a/src/main/java/org/softwarefactory/keycloak/providers/events/http/HTTPEventListenerProvider.java +++ b/src/main/java/org/softwarefactory/keycloak/providers/events/http/HTTPEventListenerProvider.java @@ -23,12 +23,12 @@ import org.keycloak.events.admin.AdminEvent; import org.keycloak.events.admin.OperationType; +import java.util.Base64; import java.util.Map; import java.util.Set; import java.lang.Exception; import okhttp3.*; -import okhttp3.OkHttpClient.Builder; import java.io.IOException; @@ -37,21 +37,20 @@ */ public class HTTPEventListenerProvider implements EventListenerProvider { private final OkHttpClient httpClient = new OkHttpClient(); + public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); private Set excludedEvents; private Set excludedAdminOperations; private String serverUri; private String username; private String password; public static final String publisherId = "keycloak"; - public String TOPIC; - public HTTPEventListenerProvider(Set excludedEvents, Set excludedAdminOperations, String serverUri, String username, String password, String topic) { + public HTTPEventListenerProvider(Set excludedEvents, Set excludedAdminOperations, String serverUri, String username, String password) { this.excludedEvents = excludedEvents; this.excludedAdminOperations = excludedAdminOperations; this.serverUri = serverUri; this.username = username; this.password = password; - this.TOPIC = topic; } @Override @@ -62,20 +61,18 @@ public void onEvent(Event event) { } else { String stringEvent = toString(event); try { - RequestBody formBody = new FormBody.Builder() - .add("json", stringEvent) - .build(); + + okhttp3.RequestBody jsonRequestBody = okhttp3.RequestBody.create(stringEvent, JSON); okhttp3.Request.Builder builder = new Request.Builder() .url(this.serverUri) .addHeader("User-Agent", "KeycloakHttp Bot"); - if (this.username != null && this.password != null) { - builder.addHeader("Authorization", "Basic " + this.username + ":" + this.password.toCharArray()); + builder.addHeader("Authorization", this.getAuthHeader()); } - Request request = builder.post(formBody) + Request request = builder.post(jsonRequestBody) .build(); Response response = httpClient.newCall(request).execute(); @@ -88,7 +85,8 @@ public void onEvent(Event event) { System.out.println(response.body().string()); } catch(Exception e) { // ? - System.out.println("UH OH!! " + e.toString()); + System.out.println("Failed to forward webhook Event " + e.toString()); + System.out.println("Request body string: " + stringEvent); e.printStackTrace(); return; } @@ -102,21 +100,19 @@ public void onEvent(AdminEvent event, boolean includeRepresentation) { return; } else { String stringEvent = toString(event); + try { - RequestBody formBody = new FormBody.Builder() - .add("json", stringEvent) - .build(); + okhttp3.RequestBody jsonRequestBody = okhttp3.RequestBody.create(stringEvent, JSON); okhttp3.Request.Builder builder = new Request.Builder() .url(this.serverUri) .addHeader("User-Agent", "KeycloakHttp Bot"); - if (this.username != null && this.password != null) { - builder.addHeader("Authorization", "Basic " + this.username + ":" + this.password.toCharArray()); + builder.addHeader("Authorization", this.getAuthHeader()); } - Request request = builder.post(formBody) + Request request = builder.post(jsonRequestBody) .build(); Response response = httpClient.newCall(request).execute(); @@ -129,71 +125,81 @@ public void onEvent(AdminEvent event, boolean includeRepresentation) { System.out.println(response.body().string()); } catch(Exception e) { // ? - System.out.println("UH OH!! " + e.toString()); + System.out.println("Failed to forward webhook AdminEvent " + e.toString()); + System.out.println("Request body string: " + stringEvent); e.printStackTrace(); return; } } } + private String getAuthHeader() { + String token = this.username + ":" + this.password; + String encodedToken = Base64.getEncoder().encodeToString(token.getBytes()); + return "Basic " + encodedToken; + } private String toString(Event event) { StringBuilder sb = new StringBuilder(); - sb.append("{'type': '"); + sb.append("{\"type\": \""); sb.append(event.getType()); - sb.append("', 'realmId': '"); + sb.append("\", \"realmId\": \""); sb.append(event.getRealmId()); - sb.append("', 'clientId': '"); + sb.append("\", \"clientId\": \""); sb.append(event.getClientId()); - sb.append("', 'userId': '"); + sb.append("\", \"userId\": \""); sb.append(event.getUserId()); - sb.append("', 'ipAddress': '"); + sb.append("\", \"ipAddress\": \""); sb.append(event.getIpAddress()); - sb.append("'"); + sb.append("\""); if (event.getError() != null) { - sb.append(", 'error': '"); + sb.append(", \"error\": \""); sb.append(event.getError()); - sb.append("'"); + sb.append("\""); } - sb.append(", 'details': {"); + sb.append(", \"details\": {"); if (event.getDetails() != null) { + int i = 0; for (Map.Entry e : event.getDetails().entrySet()) { - sb.append("'"); + sb.append("\""); sb.append(e.getKey()); - sb.append("': '"); + sb.append("\": \""); sb.append(e.getValue()); - sb.append("', "); + sb.append("\""); + if (i < event.getDetails().entrySet().size() - 1) { + sb.append(", "); + } + i = i + 1; } } sb.append("}}"); return sb.toString(); } - - + private String toString(AdminEvent adminEvent) { StringBuilder sb = new StringBuilder(); - sb.append("{'type': '"); + sb.append("{\"type\": \""); sb.append(adminEvent.getOperationType()); - sb.append("', 'realmId': '"); + sb.append("\", \"realmId\": \""); sb.append(adminEvent.getAuthDetails().getRealmId()); - sb.append("', 'clientId': '"); + sb.append("\", \"clientId\": \""); sb.append(adminEvent.getAuthDetails().getClientId()); - sb.append("', 'userId': '"); + sb.append("\", \"userId\": \""); sb.append(adminEvent.getAuthDetails().getUserId()); - sb.append("', 'ipAddress': '"); + sb.append("\", \"ipAddress\": \""); sb.append(adminEvent.getAuthDetails().getIpAddress()); - sb.append("', 'resourcePath': '"); + sb.append("\", \"resourcePath\": \""); sb.append(adminEvent.getResourcePath()); - sb.append("'"); + sb.append("\""); if (adminEvent.getError() != null) { - sb.append(", 'error': '"); + sb.append(", \"error\": \""); sb.append(adminEvent.getError()); - sb.append("'"); + sb.append("\""); } sb.append("}"); return sb.toString(); diff --git a/src/main/java/org/softwarefactory/keycloak/providers/events/http/HTTPEventListenerProviderFactory.java b/src/main/java/org/softwarefactory/keycloak/providers/events/http/HTTPEventListenerProviderFactory.java index 101a22d..3aacf9f 100755 --- a/src/main/java/org/softwarefactory/keycloak/providers/events/http/HTTPEventListenerProviderFactory.java +++ b/src/main/java/org/softwarefactory/keycloak/providers/events/http/HTTPEventListenerProviderFactory.java @@ -27,7 +27,6 @@ import java.util.HashSet; import java.util.Set; -import java.lang.Exception; /** * @author Jessy Lennee @@ -39,11 +38,10 @@ public class HTTPEventListenerProviderFactory implements EventListenerProviderFa private String serverUri; private String username; private String password; - private String topic; @Override public EventListenerProvider create(KeycloakSession session) { - return new HTTPEventListenerProvider(excludedEvents, excludedAdminOperations, serverUri, username, password, topic); + return new HTTPEventListenerProvider(excludedEvents, excludedAdminOperations, serverUri, username, password); } @Override @@ -67,7 +65,8 @@ public void init(Config.Scope config) { serverUri = config.get("serverUri", "http://nginx/frontend_dev.php/webhook/keycloak"); username = config.get("username", null); password = config.get("password", null); - topic = config.get("topic", "keycloak/events"); + + System.out.println("Forwarding keycloak events to: " + serverUri); } @Override diff --git a/target/classes/org/softwarefactory/keycloak/providers/events/http/HTTPEventListenerProvider.class b/target/classes/org/softwarefactory/keycloak/providers/events/http/HTTPEventListenerProvider.class index 5627ff0..f8d3e48 100644 Binary files a/target/classes/org/softwarefactory/keycloak/providers/events/http/HTTPEventListenerProvider.class and b/target/classes/org/softwarefactory/keycloak/providers/events/http/HTTPEventListenerProvider.class differ diff --git a/target/classes/org/softwarefactory/keycloak/providers/events/http/HTTPEventListenerProviderFactory.class b/target/classes/org/softwarefactory/keycloak/providers/events/http/HTTPEventListenerProviderFactory.class index fd62952..ff9ebc6 100644 Binary files a/target/classes/org/softwarefactory/keycloak/providers/events/http/HTTPEventListenerProviderFactory.class and b/target/classes/org/softwarefactory/keycloak/providers/events/http/HTTPEventListenerProviderFactory.class differ