This is an automated email from the ASF dual-hosted git repository. apkhmv pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push: new 7b06388aaf IGNITE-22300 Adjust EventType (#3807) 7b06388aaf is described below commit 7b06388aaf2c9d0f02404857f842c6a6a6e07710 Author: Aleksandr Pakhomov <apk...@gmail.com> AuthorDate: Fri May 24 13:23:47 2024 +0300 IGNITE-22300 Adjust EventType (#3807) Now the names are more consistent and follows same pattern. --- .../ItEventLogConfigurationValidationTest.java | 4 +- .../ignite/internal/eventlog/ItEventLogTest.java | 28 +++++++++++++- .../internal/eventlog/api/IgniteEventType.java | 6 ++- .../ignite/internal/eventlog/api/IgniteEvents.java | 8 ++-- .../internal/eventlog/event/IgniteEventsTest.java | 36 +++++++++++------ .../ConfigurationBasedChannelRegistryTest.java | 30 +++++++-------- .../internal/eventlog/impl/EventLogTest.java | 4 +- .../ignite/internal/eventlog/impl/LogSinkTest.java | 6 +-- .../ser/JacksonBasedJsonSerializerTest.java | 42 ++++++++++++++++---- .../authentication/AuthenticationManagerImpl.java | 45 +++++++++++++++++----- 10 files changed, 150 insertions(+), 59 deletions(-) diff --git a/modules/eventlog/src/integrationTest/java/org/apache/ignite/internal/eventlog/ItEventLogConfigurationValidationTest.java b/modules/eventlog/src/integrationTest/java/org/apache/ignite/internal/eventlog/ItEventLogConfigurationValidationTest.java index b232daef98..fe4bbe23dc 100644 --- a/modules/eventlog/src/integrationTest/java/org/apache/ignite/internal/eventlog/ItEventLogConfigurationValidationTest.java +++ b/modules/eventlog/src/integrationTest/java/org/apache/ignite/internal/eventlog/ItEventLogConfigurationValidationTest.java @@ -17,7 +17,7 @@ package org.apache.ignite.internal.eventlog; -import static org.apache.ignite.internal.eventlog.api.IgniteEventType.CONNECTION_CLOSED; +import static org.apache.ignite.internal.eventlog.api.IgniteEventType.CLIENT_CONNECTION_CLOSED; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -44,7 +44,7 @@ class ItEventLogConfigurationValidationTest extends ClusterPerClassIntegrationTe () -> eventLogConfiguration().change( c -> c.changeChannels().create( "testChannel2", - chC -> chC.changeEvents(CONNECTION_CLOSED.name())) + chC -> chC.changeEvents(CLIENT_CONNECTION_CLOSED.name())) ).get() ); } diff --git a/modules/eventlog/src/integrationTest/java/org/apache/ignite/internal/eventlog/ItEventLogTest.java b/modules/eventlog/src/integrationTest/java/org/apache/ignite/internal/eventlog/ItEventLogTest.java index 2b3c02598a..f8eee8f1f5 100644 --- a/modules/eventlog/src/integrationTest/java/org/apache/ignite/internal/eventlog/ItEventLogTest.java +++ b/modules/eventlog/src/integrationTest/java/org/apache/ignite/internal/eventlog/ItEventLogTest.java @@ -21,9 +21,11 @@ import static org.awaitility.Awaitility.await; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.matchesRegex; +import static org.junit.jupiter.api.Assertions.assertThrows; import java.io.IOException; import java.nio.file.Files; @@ -32,6 +34,7 @@ import java.util.List; import org.apache.ignite.InitParametersBuilder; import org.apache.ignite.client.BasicAuthenticator; import org.apache.ignite.client.IgniteClient; +import org.apache.ignite.client.IgniteClientConnectionException; import org.apache.ignite.internal.ClusterPerClassIntegrationTest; import org.apache.ignite.internal.properties.IgniteProductVersion; import org.junit.jupiter.api.BeforeAll; @@ -67,7 +70,7 @@ class ItEventLogTest extends ClusterPerClassIntegrationTest { String eventLog = "eventlog {\n" + " sinks.logSink.channel: testChannel,\n" - + " channels.testChannel.events: [USER_AUTHENTICATED],\n" + + " channels.testChannel.events: [USER_AUTHENTICATION_SUCCESS, USER_AUTHENTICATION_FAILURE],\n" + "}\n"; builder.clusterConfiguration(securityConfiguration + eventLog); @@ -89,7 +92,7 @@ class ItEventLogTest extends ClusterPerClassIntegrationTest { // And event is written in JSON format. String expectedEventJsonPattern = "\\{" - + "\"type\":\"USER_AUTHENTICATED\"," + + "\"type\":\"USER_AUTHENTICATION_SUCCESS\"," + "\"timestamp\":\\d*," + "\"productVersion\":\"" + IgniteProductVersion.VERSION_PATTERN.pattern() + "\"," + "\"user\":\\{\"username\":\"" + USERNAME + "\",\"authenticationProvider\":\"" + PROVIDER_NAME + "\"}," @@ -97,6 +100,27 @@ class ItEventLogTest extends ClusterPerClassIntegrationTest { + "}"; assertThat(readEventLog(), contains(matchesRegex(expectedEventJsonPattern))); + + // When try to authenticate with invalid credentials. + BasicAuthenticator invalidAuthenticator = BasicAuthenticator.builder().username("UNKNOWN").password("SECRET").build(); + assertThrows( + IgniteClientConnectionException.class, + () -> IgniteClient.builder().addresses("127.0.0.1:10800").authenticator(invalidAuthenticator).build() + ); + + // Then at least one more event is written to file (Can have more than one attempt to connect). + await().until(() -> readEventLog().size() > 1); + + // And event is written in JSON format. + String expectedEventJsonPatternAfterInvalidAuth = "\\{" + + "\"type\":\"USER_AUTHENTICATION_FAILURE\"," + + "\"timestamp\":\\d*," + + "\"productVersion\":\"" + IgniteProductVersion.VERSION_PATTERN.pattern() + "\"," + + "\"user\":\\{\"username\":\"SYSTEM\",\"authenticationProvider\":\"SYSTEM\"}," + + "\"fields\":\\{\"identity\":\"UNKNOWN\"}" + + "}"; + + assertThat(readEventLog(), hasItem(matchesRegex(expectedEventJsonPatternAfterInvalidAuth))); } private static List<String> readEventLog() throws IOException { diff --git a/modules/eventlog/src/main/java/org/apache/ignite/internal/eventlog/api/IgniteEventType.java b/modules/eventlog/src/main/java/org/apache/ignite/internal/eventlog/api/IgniteEventType.java index 894ef3327d..c9d655a222 100644 --- a/modules/eventlog/src/main/java/org/apache/ignite/internal/eventlog/api/IgniteEventType.java +++ b/modules/eventlog/src/main/java/org/apache/ignite/internal/eventlog/api/IgniteEventType.java @@ -25,8 +25,10 @@ import org.apache.ignite.internal.eventlog.event.EventTypeRegistry; * event type is used to filter the events in the event log. */ public enum IgniteEventType { - USER_AUTHENTICATED, - CONNECTION_CLOSED; + USER_AUTHENTICATION_SUCCESS, + USER_AUTHENTICATION_FAILURE, + CLIENT_CONNECTION_ESTABLISHED, + CLIENT_CONNECTION_CLOSED; static { // Without the following line, the IgniteEventType enum will not be registered in the EventTypeRegistry diff --git a/modules/eventlog/src/main/java/org/apache/ignite/internal/eventlog/api/IgniteEvents.java b/modules/eventlog/src/main/java/org/apache/ignite/internal/eventlog/api/IgniteEvents.java index 12f0a23c78..1b7aae4312 100644 --- a/modules/eventlog/src/main/java/org/apache/ignite/internal/eventlog/api/IgniteEvents.java +++ b/modules/eventlog/src/main/java/org/apache/ignite/internal/eventlog/api/IgniteEvents.java @@ -26,12 +26,14 @@ import org.apache.ignite.internal.eventlog.event.EventUser; * <p>If you want to create an instance of the Event with the specified type, use the {@link #create} method. * * <p>For example, to create an event of the type USER_AUTHENTICATED: - * <pre>{@code IgniteEvents.USER_AUTHENTICATED.create(EventUser.system());}</pre> + * <pre>{@code IgniteEvents.USER_AUTHENTICATION_SUCCESS.create(EventUser.system());}</pre> */ public final class IgniteEvents implements EventFactory { - public static final IgniteEvents USER_AUTHENTICATED = new IgniteEvents(IgniteEventType.USER_AUTHENTICATED.name()); + public static final IgniteEvents USER_AUTHENTICATION_SUCCESS = new IgniteEvents(IgniteEventType.USER_AUTHENTICATION_SUCCESS.name()); + public static final IgniteEvents USER_AUTHENTICATION_FAILURE = new IgniteEvents(IgniteEventType.USER_AUTHENTICATION_FAILURE.name()); - public static final IgniteEvents CONNECTION_CLOSED = new IgniteEvents(IgniteEventType.CONNECTION_CLOSED.name()); + public static final IgniteEvents CLIENT_CONNECTION_ESTABLISHED = new IgniteEvents(IgniteEventType.CLIENT_CONNECTION_ESTABLISHED.name()); + public static final IgniteEvents CLIENT_CONNECTION_CLOSED = new IgniteEvents(IgniteEventType.CLIENT_CONNECTION_CLOSED.name()); private final String type; diff --git a/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/event/IgniteEventsTest.java b/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/event/IgniteEventsTest.java index fcae17a3b8..ef738e7efc 100644 --- a/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/event/IgniteEventsTest.java +++ b/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/event/IgniteEventsTest.java @@ -35,34 +35,46 @@ class IgniteEventsTest { private static final String PROVIDER = "test_provider"; private static Stream<Arguments> events() { - Event connectionClosedEvent = IgniteEvents.CONNECTION_CLOSED.create(EventUser.of(USER, PROVIDER)); - Event connectionEstablishedEvent = IgniteEvents.USER_AUTHENTICATED.create(EventUser.of(USER, PROVIDER)); - return Stream.of( Arguments.of( - connectionClosedEvent, + IgniteEvents.CLIENT_CONNECTION_CLOSED.create(EventUser.of(USER, PROVIDER)), + Event.builder() + .type("CLIENT_CONNECTION_CLOSED") + .productVersion(IgniteProductVersion.CURRENT_VERSION.toString()) + .user(EventUser.of(USER, PROVIDER)) + ), + Arguments.of( + IgniteEvents.CLIENT_CONNECTION_ESTABLISHED.create(EventUser.of(USER, PROVIDER)), + Event.builder() + .type("CLIENT_CONNECTION_ESTABLISHED") + .productVersion(IgniteProductVersion.CURRENT_VERSION.toString()) + .user(EventUser.of(USER, PROVIDER)) + ), + Arguments.of( + IgniteEvents.USER_AUTHENTICATION_SUCCESS.create(EventUser.of(USER, PROVIDER)), Event.builder() - .type("CONNECTION_CLOSED") + .type("USER_AUTHENTICATION_SUCCESS") .productVersion(IgniteProductVersion.CURRENT_VERSION.toString()) - .timestamp(connectionClosedEvent.getTimestamp()) .user(EventUser.of(USER, PROVIDER)) - .build() + ), Arguments.of( - connectionEstablishedEvent, + IgniteEvents.USER_AUTHENTICATION_FAILURE.create(EventUser.of(USER, PROVIDER)), Event.builder() - .type("USER_AUTHENTICATED") + .type("USER_AUTHENTICATION_FAILURE") .productVersion(IgniteProductVersion.CURRENT_VERSION.toString()) - .timestamp(connectionEstablishedEvent.getTimestamp()) .user(EventUser.of(USER, PROVIDER)) - .build() + ) ); } @ParameterizedTest @MethodSource("events") - void createEvents(Event givenEvent, Event expectedEvent) { + void createEvents(Event givenEvent, EventBuilder expectedEventBuilder) { + // Timestamp should be equal, so we take it from expected event. + var expectedEvent = expectedEventBuilder.timestamp(givenEvent.getTimestamp()).build(); + assertThat(givenEvent, equalTo(expectedEvent)); } } diff --git a/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/impl/ConfigurationBasedChannelRegistryTest.java b/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/impl/ConfigurationBasedChannelRegistryTest.java index 92b54bbfab..608d91329a 100644 --- a/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/impl/ConfigurationBasedChannelRegistryTest.java +++ b/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/impl/ConfigurationBasedChannelRegistryTest.java @@ -62,14 +62,14 @@ class ConfigurationBasedChannelRegistryTest extends BaseIgniteAbstractTest { // Given configuration with a channel. cfg.channels().change(c -> c.create(TEST_CHANNEL, s -> { s.changeEnabled(true); - s.changeEvents(IgniteEventType.USER_AUTHENTICATED.name()); + s.changeEvents(IgniteEventType.USER_AUTHENTICATION_SUCCESS.name()); })).get(); // When get channel from registry. EventChannel channel = registry.getByName(TEST_CHANNEL); // Then it is configured correctly. - assertThat(channel.types(), hasItem(IgniteEventType.USER_AUTHENTICATED.name())); + assertThat(channel.types(), hasItem(IgniteEventType.USER_AUTHENTICATION_SUCCESS.name())); } @Test @@ -77,7 +77,7 @@ class ConfigurationBasedChannelRegistryTest extends BaseIgniteAbstractTest { // Given configuration with a channel. cfg.channels().change(c -> c.create(TEST_CHANNEL, s -> { s.changeEnabled(true); - s.changeEvents(IgniteEventType.USER_AUTHENTICATED.name()); + s.changeEvents(IgniteEventType.USER_AUTHENTICATION_SUCCESS.name()); })).get(); // When remove configuration entry. @@ -92,7 +92,7 @@ class ConfigurationBasedChannelRegistryTest extends BaseIgniteAbstractTest { // Given configuration with a channel. cfg.channels().change(c -> c.create(TEST_CHANNEL, s -> { s.changeEnabled(true); - s.changeEvents(IgniteEventType.USER_AUTHENTICATED.name()); + s.changeEvents(IgniteEventType.USER_AUTHENTICATION_SUCCESS.name()); })).get(); assertThat(registry.getByName(TEST_CHANNEL).types(), hasSize(1)); @@ -100,7 +100,7 @@ class ConfigurationBasedChannelRegistryTest extends BaseIgniteAbstractTest { // When update configuration entry. cfg.channels().change(c -> c.update(TEST_CHANNEL, s -> { s.changeEnabled(true); - s.changeEvents(IgniteEventType.USER_AUTHENTICATED.name(), IgniteEventType.CONNECTION_CLOSED.name()); + s.changeEvents(IgniteEventType.USER_AUTHENTICATION_SUCCESS.name(), IgniteEventType.CLIENT_CONNECTION_CLOSED.name()); })).get(); // Then channel is updated in registry and types are not the same as the were before the update. @@ -112,40 +112,40 @@ class ConfigurationBasedChannelRegistryTest extends BaseIgniteAbstractTest { // Given configuration with a channel. cfg.channels().change(c -> c.create(TEST_CHANNEL, s -> { s.changeEnabled(true); - s.changeEvents(IgniteEventType.USER_AUTHENTICATED.name()); + s.changeEvents(IgniteEventType.USER_AUTHENTICATION_SUCCESS.name()); })).get(); // Then registry returns the channel by type. - assertThat(registry.findAllChannelsByEventType(IgniteEventType.USER_AUTHENTICATED.name()), hasSize(1)); + assertThat(registry.findAllChannelsByEventType(IgniteEventType.USER_AUTHENTICATION_SUCCESS.name()), hasSize(1)); // But for another type it returns empty set. - assertThat(registry.findAllChannelsByEventType(IgniteEventType.CONNECTION_CLOSED.name()), hasSize(0)); + assertThat(registry.findAllChannelsByEventType(IgniteEventType.CLIENT_CONNECTION_CLOSED.name()), hasSize(0)); // When update configuration entry. cfg.channels().change(c -> c.update(TEST_CHANNEL, s -> { s.changeEnabled(true); - s.changeEvents(IgniteEventType.USER_AUTHENTICATED.name(), IgniteEventType.CONNECTION_CLOSED.name()); + s.changeEvents(IgniteEventType.USER_AUTHENTICATION_SUCCESS.name(), IgniteEventType.CLIENT_CONNECTION_CLOSED.name()); })).get(); // Then registry returns the channel by type. - assertThat(registry.findAllChannelsByEventType(IgniteEventType.USER_AUTHENTICATED.name()), hasSize(1)); - assertThat(registry.findAllChannelsByEventType(IgniteEventType.CONNECTION_CLOSED.name()), hasSize(1)); + assertThat(registry.findAllChannelsByEventType(IgniteEventType.USER_AUTHENTICATION_SUCCESS.name()), hasSize(1)); + assertThat(registry.findAllChannelsByEventType(IgniteEventType.CLIENT_CONNECTION_CLOSED.name()), hasSize(1)); // When add new channel. cfg.channels().change(c -> c.create("newChannel", s -> { s.changeEnabled(true); - s.changeEvents(IgniteEventType.USER_AUTHENTICATED.name()); + s.changeEvents(IgniteEventType.USER_AUTHENTICATION_SUCCESS.name()); })).get(); // Then. - assertThat(registry.findAllChannelsByEventType(IgniteEventType.USER_AUTHENTICATED.name()), hasSize(2)); - assertThat(registry.findAllChannelsByEventType(IgniteEventType.CONNECTION_CLOSED.name()), hasSize(1)); + assertThat(registry.findAllChannelsByEventType(IgniteEventType.USER_AUTHENTICATION_SUCCESS.name()), hasSize(2)); + assertThat(registry.findAllChannelsByEventType(IgniteEventType.CLIENT_CONNECTION_CLOSED.name()), hasSize(1)); } @Test void enableDisable() throws Exception { // Given configuration with a channel. cfg.channels().change(c -> c.create(TEST_CHANNEL, s -> { - s.changeEvents(IgniteEventType.USER_AUTHENTICATED.name()); + s.changeEvents(IgniteEventType.USER_AUTHENTICATION_SUCCESS.name()); })).get(); assertThat(registry.getByName(TEST_CHANNEL), not(nullValue())); diff --git a/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/impl/EventLogTest.java b/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/impl/EventLogTest.java index f5b19ca59f..888aa9a007 100644 --- a/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/impl/EventLogTest.java +++ b/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/impl/EventLogTest.java @@ -40,7 +40,7 @@ import org.junit.jupiter.api.Test; class EventLogTest { private static final EventUser TEST_USER = EventUser.of("testuser", "basicAuthenticator"); - private static final Event TEST_EVENT = IgniteEvents.USER_AUTHENTICATED.create(TEST_USER); + private static final Event TEST_EVENT = IgniteEvents.USER_AUTHENTICATION_SUCCESS.create(TEST_USER); private static final String TEST_CHANNEL_NAME = "testChannel"; private EventLog eventLog; @@ -83,7 +83,7 @@ class EventLogTest { assertThat(container, hasItem(TEST_EVENT)); // When log event with a type that is not supported by the channel. - Event event = IgniteEvents.CONNECTION_CLOSED.create(TEST_USER); + Event event = IgniteEvents.CLIENT_CONNECTION_CLOSED.create(TEST_USER); // Then nothing thrown. assertDoesNotThrow(() -> eventLog.log(() -> event)); diff --git a/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/impl/LogSinkTest.java b/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/impl/LogSinkTest.java index faf4cdb518..af1589dafe 100644 --- a/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/impl/LogSinkTest.java +++ b/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/impl/LogSinkTest.java @@ -72,7 +72,7 @@ class LogSinkTest extends BaseIgniteAbstractTest { Sink logSink = new LogSinkFactory(new EventSerializerFactory().createEventSerializer()) .createSink(cfg.sinks().get("logSink").value()); // And event. - Event event = IgniteEvents.USER_AUTHENTICATED.create( + Event event = IgniteEvents.USER_AUTHENTICATION_SUCCESS.create( EventUser.of("user1", "basicProvider") ); @@ -83,7 +83,7 @@ class LogSinkTest extends BaseIgniteAbstractTest { await().untilAsserted(() -> assertThat(Files.readAllLines(eventlogPath), hasSize(1))); // And event is written in JSON format. var expectedEventJson = "{" - + "\"type\":\"USER_AUTHENTICATED\"," + + "\"type\":\"USER_AUTHENTICATION_SUCCESS\"," + "\"timestamp\":" + event.getTimestamp() + "," + "\"productVersion\":\"" + event.getProductVersion() + "\"," + "\"user\":{\"username\":\"user1\",\"authenticationProvider\":\"basicProvider\"}," @@ -92,7 +92,7 @@ class LogSinkTest extends BaseIgniteAbstractTest { assertThat(Files.readAllLines(eventlogPath), hasItem(expectedEventJson)); // When write one more event. - Event event2 = IgniteEvents.CONNECTION_CLOSED.create( + Event event2 = IgniteEvents.CLIENT_CONNECTION_CLOSED.create( EventUser.of("user2", "basicProvider") ); diff --git a/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/ser/JacksonBasedJsonSerializerTest.java b/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/ser/JacksonBasedJsonSerializerTest.java index 5615536041..845f79a3de 100644 --- a/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/ser/JacksonBasedJsonSerializerTest.java +++ b/modules/eventlog/src/test/java/org/apache/ignite/internal/eventlog/ser/JacksonBasedJsonSerializerTest.java @@ -34,12 +34,12 @@ class JacksonBasedJsonSerializerTest { private static Stream<Arguments> events() { return Stream.of( Arguments.of( - IgniteEvents.CONNECTION_CLOSED.builder() + IgniteEvents.CLIENT_CONNECTION_CLOSED.builder() .productVersion("3.0.0") .timestamp(1234567890) .user(EventUser.of("test_user", "test_provider")) .build(), - "{\"type\":\"CONNECTION_CLOSED\"," + "{\"type\":\"CLIENT_CONNECTION_CLOSED\"," + "\"timestamp\":1234567890," + "\"productVersion\":\"3.0.0\"," + "\"user\":{\"username\":\"test_user\",\"authenticationProvider\":\"test_provider\"}," @@ -47,12 +47,12 @@ class JacksonBasedJsonSerializerTest { + "}" ), Arguments.of( - IgniteEvents.USER_AUTHENTICATED.builder() + IgniteEvents.CLIENT_CONNECTION_ESTABLISHED.builder() .productVersion("3.0.0") .timestamp(1234567890) .user(EventUser.of("test_user", "test_provider")) .build(), - "{\"type\":\"USER_AUTHENTICATED\"," + "{\"type\":\"CLIENT_CONNECTION_ESTABLISHED\"," + "\"timestamp\":1234567890," + "\"productVersion\":\"3.0.0\"," + "\"user\":{\"username\":\"test_user\",\"authenticationProvider\":\"test_provider\"}," @@ -60,13 +60,39 @@ class JacksonBasedJsonSerializerTest { + "}" ), Arguments.of( - IgniteEvents.USER_AUTHENTICATED.builder() + IgniteEvents.USER_AUTHENTICATION_FAILURE.builder() + .productVersion("3.0.0") + .timestamp(1234567890) + .user(EventUser.of("test_user", "test_provider")) + .build(), + "{\"type\":\"USER_AUTHENTICATION_FAILURE\"," + + "\"timestamp\":1234567890," + + "\"productVersion\":\"3.0.0\"," + + "\"user\":{\"username\":\"test_user\",\"authenticationProvider\":\"test_provider\"}," + + "\"fields\":{}" + + "}" + ), + Arguments.of( + IgniteEvents.USER_AUTHENTICATION_SUCCESS.builder() + .productVersion("3.0.0") + .timestamp(1234567890) + .user(EventUser.of("test_user", "test_provider")) + .build(), + "{\"type\":\"USER_AUTHENTICATION_SUCCESS\"," + + "\"timestamp\":1234567890," + + "\"productVersion\":\"3.0.0\"," + + "\"user\":{\"username\":\"test_user\",\"authenticationProvider\":\"test_provider\"}," + + "\"fields\":{}" + + "}" + ), + Arguments.of( + IgniteEvents.USER_AUTHENTICATION_SUCCESS.builder() .productVersion("3.0.0") .timestamp(1234567890) .user(EventUser.of("test_user", "test_provider")) .fields(Map.of("ip", "127.0.0.1", "id", "123")) .build(), - "{\"type\":\"USER_AUTHENTICATED\"," + "{\"type\":\"USER_AUTHENTICATION_SUCCESS\"," + "\"timestamp\":1234567890," + "\"productVersion\":\"3.0.0\"," + "\"user\":{\"username\":\"test_user\",\"authenticationProvider\":\"test_provider\"}," @@ -89,7 +115,7 @@ class JacksonBasedJsonSerializerTest { + "}" ), Arguments.of( - IgniteEvents.USER_AUTHENTICATED.builder() + IgniteEvents.USER_AUTHENTICATION_SUCCESS.builder() .productVersion("3.0.0") .timestamp(1234567890) .user(EventUser.of("test_user", "test_provider")) @@ -99,7 +125,7 @@ class JacksonBasedJsonSerializerTest { "message", new Message(1, "foo") )) .build(), - "{\"type\":\"USER_AUTHENTICATED\"," + "{\"type\":\"USER_AUTHENTICATION_SUCCESS\"," + "\"timestamp\":1234567890," + "\"productVersion\":\"3.0.0\"," + "\"user\":{\"username\":\"test_user\",\"authenticationProvider\":\"test_provider\"}," diff --git a/modules/security/src/main/java/org/apache/ignite/internal/security/authentication/AuthenticationManagerImpl.java b/modules/security/src/main/java/org/apache/ignite/internal/security/authentication/AuthenticationManagerImpl.java index 6ee501a7b7..d79812e16a 100644 --- a/modules/security/src/main/java/org/apache/ignite/internal/security/authentication/AuthenticationManagerImpl.java +++ b/modules/security/src/main/java/org/apache/ignite/internal/security/authentication/AuthenticationManagerImpl.java @@ -23,6 +23,7 @@ import static org.apache.ignite.internal.util.CompletableFutures.nullCompletedFu import java.util.ArrayList; import java.util.Comparator; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.concurrent.CompletableFuture; import java.util.concurrent.locks.ReadWriteLock; @@ -167,14 +168,6 @@ public class AuthenticationManagerImpl .map(authenticator -> authenticate(authenticator, authenticationRequest)) .filter(Objects::nonNull) .findFirst() - .map(userDetails -> { - eventLog.log(() -> - IgniteEvents.USER_AUTHENTICATED.create(EventUser.of( - userDetails.username(), userDetails.providerName() - ))); - - return userDetails; - }) .orElseThrow(() -> new InvalidCredentialsException("Authentication failed")); } else { return UserDetails.UNKNOWN; @@ -185,17 +178,49 @@ public class AuthenticationManagerImpl } @Nullable - private static UserDetails authenticate(Authenticator authenticator, AuthenticationRequest<?, ?> authenticationRequest) { + private UserDetails authenticate( + Authenticator authenticator, + AuthenticationRequest<?, ?> authenticationRequest + ) { try { - return authenticator.authenticate(authenticationRequest); + var userDetails = authenticator.authenticate(authenticationRequest); + if (userDetails != null) { + logUserAuthenticated(userDetails); + } + return userDetails; } catch (InvalidCredentialsException | UnsupportedAuthenticationTypeException exception) { + logAuthenticationFailure(authenticationRequest); return null; } catch (Exception e) { + logAuthenticationFailure(authenticationRequest); LOG.error("Unexpected exception during authentication", e); return null; } } + private void logAuthenticationFailure(AuthenticationRequest<?, ?> authenticationRequest) { + eventLog.log(() -> + IgniteEvents.USER_AUTHENTICATION_FAILURE.builder() + .user(EventUser.system()) + .fields(Map.of("identity", tryGetUsernameOrUnknown(authenticationRequest))) + .build() + ); + } + + private static String tryGetUsernameOrUnknown(AuthenticationRequest<?, ?> authenticationRequest) { + if (authenticationRequest instanceof UsernamePasswordRequest) { + return ((UsernamePasswordRequest) authenticationRequest).getIdentity(); + } + return "UNKNOWN_AUTHENTICATION_TYPE"; + } + + private void logUserAuthenticated(UserDetails userDetails) { + eventLog.log(() -> + IgniteEvents.USER_AUTHENTICATION_SUCCESS.create(EventUser.of( + userDetails.username(), userDetails.providerName() + ))); + } + private void refreshProviders(@Nullable SecurityView view) { rwLock.writeLock().lock(); try {