Polish audit event endpoint support
Closes gh-6579
This commit is contained in:
@@ -34,6 +34,7 @@ import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.lang.UsesJava8;
|
||||
|
||||
// Flyway must go first
|
||||
@SpringBootApplication
|
||||
@@ -59,12 +60,16 @@ public class SpringBootHypermediaApplication implements CommandLineRunner {
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
this.auditEventRepository.add(new AuditEvent(Date.from(Instant.parse(
|
||||
"2016-11-01T11:00:00Z")), "user", "AUTHENTICATION_FAILURE",
|
||||
Collections.emptyMap()));
|
||||
this.auditEventRepository.add(new AuditEvent(Date.from(Instant.parse(
|
||||
"2016-11-01T12:00:00Z")), "admin", "AUTHENTICATION_SUCCESS",
|
||||
Collections.emptyMap()));
|
||||
this.auditEventRepository.add(
|
||||
createEvent("2016-11-01T11:00:00Z", "user", "AUTHENTICATION_FAILURE"));
|
||||
this.auditEventRepository.add(
|
||||
createEvent("2016-11-01T12:00:00Z", "admin", "AUTHENTICATION_SUCCESS"));
|
||||
}
|
||||
|
||||
@UsesJava8
|
||||
private AuditEvent createEvent(String instant, String principal, String type) {
|
||||
return new AuditEvent(Date.from(Instant.parse(instant)), principal, type,
|
||||
Collections.<String, Object>emptyMap());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
package org.springframework.boot.actuate.endpoint.mvc;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.boot.actuate.audit.AuditEvent;
|
||||
import org.springframework.boot.actuate.audit.AuditEventRepository;
|
||||
@@ -34,6 +35,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
||||
* {@link MvcEndpoint} to expose {@link AuditEvent}s.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
* @author Phillip Webb
|
||||
* @since 1.5.0
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "endpoints.auditevents")
|
||||
@@ -47,41 +49,18 @@ public class AuditEventsMvcEndpoint extends AbstractNamedMvcEndpoint {
|
||||
this.auditEventRepository = auditEventRepository;
|
||||
}
|
||||
|
||||
@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE, params = { "after" })
|
||||
@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ResponseBody
|
||||
public ResponseEntity<?> findByAfter(
|
||||
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssZ") Date after) {
|
||||
public ResponseEntity<?> findByPrincipalAndAfterAndType(
|
||||
@RequestParam(required = false) String principal,
|
||||
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssZ") Date after,
|
||||
@RequestParam(required = false) String type) {
|
||||
if (!isEnabled()) {
|
||||
return DISABLED_RESPONSE;
|
||||
}
|
||||
List<AuditEvent> auditEvents = this.auditEventRepository.find(after);
|
||||
return ResponseEntity.ok(auditEvents);
|
||||
}
|
||||
|
||||
@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE,
|
||||
params = { "principal", "after" })
|
||||
@ResponseBody
|
||||
public ResponseEntity<?> findByPrincipalAndAfter(@RequestParam String principal,
|
||||
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssZ") Date after) {
|
||||
if (!isEnabled()) {
|
||||
return DISABLED_RESPONSE;
|
||||
}
|
||||
List<AuditEvent> auditEvents = this.auditEventRepository.find(principal, after);
|
||||
return ResponseEntity.ok(auditEvents);
|
||||
}
|
||||
|
||||
@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE,
|
||||
params = { "principal", "after", "type" })
|
||||
@ResponseBody
|
||||
public ResponseEntity<?> findByPrincipalAndAfterAndType(@RequestParam String principal,
|
||||
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssZ") Date after,
|
||||
@RequestParam String type) {
|
||||
if (!isEnabled()) {
|
||||
return DISABLED_RESPONSE;
|
||||
}
|
||||
List<AuditEvent> auditEvents = this.auditEventRepository.find(principal, after,
|
||||
type);
|
||||
return ResponseEntity.ok(auditEvents);
|
||||
Map<Object, Object> result = new LinkedHashMap<Object, Object>();
|
||||
result.put("events", this.auditEventRepository.find(principal, after, type));
|
||||
return ResponseEntity.ok(result);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -109,8 +109,7 @@ public class EndpointMvcIntegrationTests {
|
||||
|
||||
private final List<HttpMessageConverter<?>> converters;
|
||||
|
||||
public Application(
|
||||
ObjectProvider<List<HttpMessageConverter<?>>> converters) {
|
||||
public Application(ObjectProvider<List<HttpMessageConverter<?>>> converters) {
|
||||
this.converters = converters.getIfAvailable();
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
@@ -55,6 +56,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
*/
|
||||
@SpringBootTest
|
||||
@RunWith(SpringRunner.class)
|
||||
@TestPropertySource(properties = "management.security.enabled=false")
|
||||
public class AuditEventsMvcEndpointTests {
|
||||
|
||||
@Autowired
|
||||
@@ -78,26 +80,27 @@ public class AuditEventsMvcEndpointTests {
|
||||
@Test
|
||||
public void invokeFilterByDateAfter() throws Exception {
|
||||
this.mvc.perform(get("/auditevents").param("after", "2016-11-01T13:00:00+0000"))
|
||||
.andExpect(status().isOk()).andExpect(content().string("[]"));
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().string("{\"events\":[]}"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeFilterByPrincipalAndDateAfter() throws Exception {
|
||||
this.mvc.perform(get("/auditevents").param("principal", "user")
|
||||
.param("after", "2016-11-01T10:00:00+0000"))
|
||||
this.mvc.perform(get("/auditevents").param("principal", "user").param("after",
|
||||
"2016-11-01T10:00:00+0000"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().string(containsString(
|
||||
"\"principal\":\"user\",\"type\":\"login\"")))
|
||||
.andExpect(content().string(
|
||||
containsString("\"principal\":\"user\",\"type\":\"login\"")))
|
||||
.andExpect(content().string(not(containsString("admin"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeFilterByPrincipalAndDateAfterAndType() throws Exception {
|
||||
this.mvc.perform(get("/auditevents").param("principal", "admin")
|
||||
.param("after", "2016-11-01T10:00:00+0000")
|
||||
.param("type", "logout")).andExpect(status().isOk())
|
||||
.andExpect(content().string(containsString(
|
||||
"\"principal\":\"admin\",\"type\":\"logout\"")))
|
||||
.param("after", "2016-11-01T10:00:00+0000").param("type", "logout"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().string(
|
||||
containsString("\"principal\":\"admin\",\"type\":\"logout\"")))
|
||||
.andExpect(content().string(not(containsString("login"))));
|
||||
}
|
||||
|
||||
@@ -111,15 +114,17 @@ public class AuditEventsMvcEndpointTests {
|
||||
@Bean
|
||||
public AuditEventRepository auditEventsRepository() {
|
||||
AuditEventRepository repository = new InMemoryAuditEventRepository(3);
|
||||
repository.add(new AuditEvent(Date.from(Instant.parse(
|
||||
"2016-11-01T11:00:00Z")), "admin", "login", Collections.emptyMap()));
|
||||
repository.add(new AuditEvent(Date.from(Instant.parse(
|
||||
"2016-11-01T12:00:00Z")), "admin", "logout", Collections.emptyMap()));
|
||||
repository.add(new AuditEvent(Date.from(Instant.parse(
|
||||
"2016-11-01T12:00:00Z")), "user", "login", Collections.emptyMap()));
|
||||
repository.add(createEvent("2016-11-01T11:00:00Z", "admin", "login"));
|
||||
repository.add(createEvent("2016-11-01T12:00:00Z", "admin", "logout"));
|
||||
repository.add(createEvent("2016-11-01T12:00:00Z", "user", "login"));
|
||||
return repository;
|
||||
}
|
||||
|
||||
private AuditEvent createEvent(String instant, String principal, String type) {
|
||||
return new AuditEvent(Date.from(Instant.parse(instant)), principal, type,
|
||||
Collections.<String, Object>emptyMap());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user