View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
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 }