Check realm from context for null, fix #25 #26

Merged
sschnabe merged 1 commit from nullsafe into main 2023-04-24 14:22:46 +02:00
2 changed files with 123 additions and 7 deletions
Showing only changes of commit 718ec1c1a8 - Show all commits

View file

@ -1,10 +1,14 @@
package io.kokuwa.keycloak.metrics;
import java.util.Optional;
import org.jboss.logging.Logger;
import org.keycloak.events.Event;
import org.keycloak.events.EventListenerProvider;
import org.keycloak.events.admin.AdminEvent;
import org.keycloak.models.KeycloakContext;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import io.micrometer.core.instrument.MeterRegistry;
@ -20,7 +24,7 @@ public class MicrometerEventListener implements EventListenerProvider, AutoClose
private final KeycloakSession session;
private final boolean replace;
public MicrometerEventListener(MeterRegistry registry, KeycloakSession session, boolean replaceId) {
MicrometerEventListener(MeterRegistry registry, KeycloakSession session, boolean replaceId) {
this.registry = registry;
this.session = session;
this.replace = replaceId;
@ -50,12 +54,17 @@ public class MicrometerEventListener implements EventListenerProvider, AutoClose
public void close() {}
private String getRealmName(String id) {
var model = session.getContext().getRealm();
if (id == null || id.equals(model.getId())) {
return model.getName();
}
log.warnv("Failed to resolve realmName for id {0}", id);
return id;
return Optional.ofNullable(session.getContext()).map(KeycloakContext::getRealm)
.filter(realm -> id == null || id.equals(realm.getId()))
.or(() -> {
log.tracev("Context realm was empty with id {0}", id);
return Optional.ofNullable(id).map(session.realms()::getRealm);
})
.map(RealmModel::getName)
.orElseGet(() -> {
log.warnv("Failed to find realm with id {0}", id);
return id;
});
}
private String toBlank(Object value) {

View file

@ -25,6 +25,7 @@ import org.keycloak.events.admin.ResourceType;
import org.keycloak.models.KeycloakContext;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RealmProvider;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
@ -46,6 +47,8 @@ public class MicrometerEventListenerTest {
@Mock
RealmModel realmModel;
@Mock
RealmProvider realmProvider;
@Mock
KeycloakContext context;
@Mock
MeterRegistry registry;
@ -116,6 +119,58 @@ public class MicrometerEventListenerTest {
assertEvent(realmName, "", "", "");
}
@DisplayName("replace(true) - context is null")
@Test
void replaceFieldsContextNull() {
var realmId = UUID.randomUUID().toString();
var realmName = UUID.randomUUID().toString();
var clientId = UUID.randomUUID().toString();
var type = EventType.LOGIN_ERROR;
when(session.realms()).thenReturn(realmProvider);
when(realmProvider.getRealm(realmId)).thenReturn(realmModel);
when(realmModel.getName()).thenReturn(realmName);
listener(true).onEvent(toEvent(realmId, clientId, type, null));
assertEvent(realmName, clientId, type.toString(), "");
}
@DisplayName("replace(true) - context is empty")
@Test
void replaceFieldsContextEmpty() {
var realmId = UUID.randomUUID().toString();
var realmName = UUID.randomUUID().toString();
var clientId = UUID.randomUUID().toString();
var type = EventType.LOGIN_ERROR;
when(session.getContext()).thenReturn(context);
when(session.realms()).thenReturn(realmProvider);
when(realmProvider.getRealm(realmId)).thenReturn(realmModel);
when(realmModel.getName()).thenReturn(realmName);
listener(true).onEvent(toEvent(realmId, clientId, type, null));
assertEvent(realmName, clientId, type.toString(), "");
}
@DisplayName("replace(true) - realmId is unknown")
@Test
void replaceFieldsRealmIdUnknown() {
var realmId = UUID.randomUUID().toString();
var clientId = UUID.randomUUID().toString();
var type = EventType.LOGIN_ERROR;
when(session.getContext()).thenReturn(context);
when(session.realms()).thenReturn(realmProvider);
when(context.getRealm()).thenReturn(realmModel);
when(realmModel.getId()).thenReturn(UUID.randomUUID().toString());
listener(true).onEvent(toEvent(realmId, clientId, type, null));
assertEvent(realmId, clientId, type.toString(), "");
}
@DisplayName("replace(false) - without error")
@Test
void notReplaceWithoutError() {
@ -221,6 +276,58 @@ public class MicrometerEventListenerTest {
assertAdminEvent(realmName, "", "", "");
}
@DisplayName("replace(true) - context is null")
@Test
void replaceFieldsContextNull() {
var realmId = UUID.randomUUID().toString();
var realmName = UUID.randomUUID().toString();
var resource = ResourceType.USER;
var operation = OperationType.CREATE;
when(session.realms()).thenReturn(realmProvider);
when(realmProvider.getRealm(realmId)).thenReturn(realmModel);
when(realmModel.getName()).thenReturn(realmName);
listener(true).onEvent(toAdminEvent(realmId, resource, operation, null), false);
assertAdminEvent(realmName, resource.toString(), operation.toString(), "");
}
@DisplayName("replace(true) - context is empty")
@Test
void replaceFieldsContextEmpty() {
var realmId = UUID.randomUUID().toString();
var realmName = UUID.randomUUID().toString();
var resource = ResourceType.USER;
var operation = OperationType.CREATE;
when(session.getContext()).thenReturn(context);
when(session.realms()).thenReturn(realmProvider);
when(realmProvider.getRealm(realmId)).thenReturn(realmModel);
when(realmModel.getName()).thenReturn(realmName);
listener(true).onEvent(toAdminEvent(realmId, resource, operation, null), false);
assertAdminEvent(realmName, resource.toString(), operation.toString(), "");
}
@DisplayName("replace(true) - realmId is unknown")
@Test
void replaceFieldsRealmIdUnknown() {
var realmId = UUID.randomUUID().toString();
var resource = ResourceType.USER;
var operation = OperationType.CREATE;
when(session.getContext()).thenReturn(context);
when(session.realms()).thenReturn(realmProvider);
when(context.getRealm()).thenReturn(realmModel);
when(realmModel.getId()).thenReturn(UUID.randomUUID().toString());
listener(true).onEvent(toAdminEvent(realmId, resource, operation, null), false);
assertAdminEvent(realmId, resource.toString(), operation.toString(), "");
}
@DisplayName("replace(false) - without error")
@Test
void noReplaceWithoutError() {