1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.wa.starter.events;
20
21 import com.fasterxml.jackson.core.JsonProcessingException;
22 import com.fasterxml.jackson.databind.json.JsonMapper;
23 import java.time.Instant;
24 import java.time.OffsetDateTime;
25 import java.time.ZoneId;
26 import java.util.HashMap;
27 import java.util.Map;
28 import java.util.stream.Stream;
29 import org.apache.commons.lang3.StringUtils;
30 import org.apache.syncope.common.lib.audit.AuditEntry;
31 import org.apache.syncope.common.lib.types.AuditElements;
32 import org.apache.syncope.common.lib.types.AuditLoggerName;
33 import org.apache.syncope.common.rest.api.service.AuditService;
34 import org.apache.syncope.wa.bootstrap.WARestClient;
35 import org.apereo.cas.support.events.CasEventRepositoryFilter;
36 import org.apereo.cas.support.events.dao.AbstractCasEventRepository;
37 import org.apereo.cas.support.events.dao.CasEvent;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41 public class WAEventRepository extends AbstractCasEventRepository {
42
43 private static final Logger LOG = LoggerFactory.getLogger(WAEventRepository.class);
44
45 private static final JsonMapper MAPPER = JsonMapper.builder().findAndAddModules().build();
46
47 private final WARestClient waRestClient;
48
49 public WAEventRepository(
50 final CasEventRepositoryFilter eventRepositoryFilter,
51 final WARestClient restClient) {
52
53 super(eventRepositoryFilter);
54 this.waRestClient = restClient;
55 }
56
57 public void put(final Map<String, String> properties, final String key, final String value) {
58 if (StringUtils.isNotBlank(value)) {
59 properties.put(key, value);
60 }
61 }
62
63 @Override
64 public CasEvent saveInternal(final CasEvent event) {
65 if (!waRestClient.isReady()) {
66 LOG.debug("Syncope client is not yet ready to store audit record");
67 return null;
68 }
69
70 LOG.debug("Saving WA events");
71 try {
72 Map<String, String> properties = new HashMap<>();
73 if (event.getGeoLocation() != null) {
74 put(properties, "geoLatitude", event.getGeoLocation().getLatitude());
75 put(properties, "geoLongitude", event.getGeoLocation().getLongitude());
76 put(properties, "geoAccuracy", event.getGeoLocation().getAccuracy());
77 put(properties, "geoTimestamp", event.getGeoLocation().getTimestamp());
78 }
79 put(properties, "clientIpAddress", event.getClientIpAddress());
80 put(properties, "serverIpAddress", event.getServerIpAddress());
81
82 String output = MAPPER.writeValueAsString(properties);
83
84 AuditEntry auditEntry = new AuditEntry();
85 auditEntry.setWho(event.getPrincipalId());
86 if (event.getTimestamp() != null) {
87 auditEntry.setDate(OffsetDateTime.ofInstant(
88 Instant.ofEpochMilli(event.getTimestamp()), ZoneId.systemDefault()));
89 }
90 auditEntry.setOutput(output);
91 AuditLoggerName auditLogger = new AuditLoggerName(
92 AuditElements.EventCategoryType.WA,
93 null,
94 event.getType().toUpperCase(),
95 String.valueOf(event.getId()),
96 AuditElements.Result.SUCCESS);
97 auditEntry.setLogger(auditLogger);
98 waRestClient.getService(AuditService.class).create(auditEntry);
99 } catch (JsonProcessingException e) {
100 LOG.error("During serialization", e);
101 }
102 return event;
103 }
104
105 @Override
106 public Stream<? extends CasEvent> load() {
107 throw new UnsupportedOperationException("Fetching authentication events from WA is not supported");
108 }
109 }