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.u2f;
20
21 import com.github.benmanes.caffeine.cache.LoadingCache;
22 import java.time.OffsetDateTime;
23 import java.time.ZoneId;
24 import java.util.Collection;
25 import java.util.Objects;
26 import java.util.stream.Collectors;
27 import org.apache.syncope.common.lib.SyncopeClientException;
28 import org.apache.syncope.common.lib.types.ClientExceptionType;
29 import org.apache.syncope.common.lib.wa.U2FDevice;
30 import org.apache.syncope.common.rest.api.beans.U2FDeviceQuery;
31 import org.apache.syncope.common.rest.api.service.wa.U2FRegistrationService;
32 import org.apache.syncope.wa.bootstrap.WARestClient;
33 import org.apereo.cas.adaptors.u2f.storage.BaseU2FDeviceRepository;
34 import org.apereo.cas.adaptors.u2f.storage.U2FDeviceRegistration;
35 import org.apereo.cas.configuration.CasConfigurationProperties;
36 import org.apereo.cas.util.crypto.CipherExecutor;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39 import org.springframework.util.CollectionUtils;
40
41 public class WAU2FDeviceRepository extends BaseU2FDeviceRepository {
42
43 private static final Logger LOG = LoggerFactory.getLogger(WAU2FDeviceRepository.class);
44
45 protected static U2FDeviceRegistration parseRegistrationRecord(final String owner, final U2FDevice device) {
46 try {
47 return U2FDeviceRegistration.builder().
48 id(device.getId()).
49 username(owner).
50 record(device.getRecord()).
51 createdDate(device.getIssueDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate()).
52 build();
53 } catch (Exception e) {
54 LOG.error(e.getMessage(), e);
55 }
56 return null;
57 }
58
59 protected final WARestClient waRestClient;
60
61 protected final OffsetDateTime expirationDate;
62
63 public WAU2FDeviceRepository(
64 final CasConfigurationProperties casProperties,
65 final LoadingCache<String, String> requestStorage,
66 final WARestClient waRestClient,
67 final OffsetDateTime expirationDate) {
68
69 super(casProperties, requestStorage, CipherExecutor.noOpOfSerializableToString());
70 this.waRestClient = waRestClient;
71 this.expirationDate = expirationDate;
72 }
73
74 protected U2FRegistrationService service() {
75 return waRestClient.getService(U2FRegistrationService.class);
76 }
77
78 @Override
79 public Collection<? extends U2FDeviceRegistration> getRegisteredDevices(final String owner) {
80 return service().
81 search(new U2FDeviceQuery.Builder().owner(owner).expirationDate(expirationDate).build()).getResult().
82 stream().
83 map(device -> parseRegistrationRecord(owner, device)).
84 filter(Objects::nonNull).
85 collect(Collectors.toList());
86 }
87
88 @Override
89 public Collection<? extends U2FDeviceRegistration> getRegisteredDevices() {
90 return service().search(new U2FDeviceQuery.Builder().expirationDate(expirationDate).build()).getResult().
91 stream().
92 map(device -> parseRegistrationRecord("", device)).
93 filter(Objects::nonNull).
94 collect(Collectors.toList());
95 }
96
97 @Override
98 public U2FDeviceRegistration registerDevice(final U2FDeviceRegistration registration) {
99 U2FDevice record = new U2FDevice.Builder().
100 issueDate(OffsetDateTime.of(
101 registration.getCreatedDate().atStartOfDay(), OffsetDateTime.now().getOffset())).
102 record(registration.getRecord()).
103 id(registration.getId()).
104 build();
105 service().create(registration.getUsername(), record);
106 return parseRegistrationRecord(registration.getUsername(), record);
107 }
108
109 @Override
110 public void deleteRegisteredDevice(final U2FDeviceRegistration registration) {
111 service().delete(new U2FDeviceQuery.Builder().id(registration.getId()).build());
112 }
113
114 @Override
115 public boolean isDeviceRegisteredFor(final String owner) {
116 try {
117 Collection<? extends U2FDeviceRegistration> devices = getRegisteredDevices(owner);
118 return !CollectionUtils.isEmpty(devices);
119 } catch (final SyncopeClientException e) {
120 if (e.getType() == ClientExceptionType.NotFound) {
121 LOG.info("Could not locate account for owner {}", owner);
122 } else {
123 LOG.error(e.getMessage(), e);
124 }
125 }
126 return false;
127 }
128
129 @Override
130 public void clean() {
131 service().delete(new U2FDeviceQuery.Builder().expirationDate(expirationDate).build());
132 }
133
134 @Override
135 public void removeAll() {
136 service().delete(new U2FDeviceQuery.Builder().build());
137 }
138 }