1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.core.logic;
20
21 import java.lang.reflect.Method;
22 import java.util.List;
23 import java.util.stream.Collectors;
24 import java.util.stream.Stream;
25 import org.apache.commons.lang3.ArrayUtils;
26 import org.apache.syncope.common.keymaster.client.api.ServiceOps;
27 import org.apache.syncope.common.lib.SyncopeClientException;
28 import org.apache.syncope.common.lib.to.ClientAppTO;
29 import org.apache.syncope.common.lib.types.AMEntitlement;
30 import org.apache.syncope.common.lib.types.ClientAppType;
31 import org.apache.syncope.common.lib.types.ClientExceptionType;
32 import org.apache.syncope.core.persistence.api.dao.CASSPClientAppDAO;
33 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
34 import org.apache.syncope.core.persistence.api.dao.OIDCRPClientAppDAO;
35 import org.apache.syncope.core.persistence.api.dao.SAML2SPClientAppDAO;
36 import org.apache.syncope.core.persistence.api.entity.am.CASSPClientApp;
37 import org.apache.syncope.core.persistence.api.entity.am.ClientApp;
38 import org.apache.syncope.core.persistence.api.entity.am.ClientAppUtils;
39 import org.apache.syncope.core.persistence.api.entity.am.ClientAppUtilsFactory;
40 import org.apache.syncope.core.persistence.api.entity.am.OIDCRPClientApp;
41 import org.apache.syncope.core.persistence.api.entity.am.SAML2SPClientApp;
42 import org.apache.syncope.core.provisioning.api.data.ClientAppDataBinder;
43 import org.springframework.security.access.prepost.PreAuthorize;
44 import org.springframework.transaction.annotation.Transactional;
45
46 public class ClientAppLogic extends AbstractTransactionalLogic<ClientAppTO> {
47
48 protected final ServiceOps serviceOps;
49
50 protected final ClientAppUtilsFactory clientAppUtilsFactory;
51
52 protected final ClientAppDataBinder binder;
53
54 protected final CASSPClientAppDAO casSPClientAppDAO;
55
56 protected final OIDCRPClientAppDAO oidcRPClientAppDAO;
57
58 protected final SAML2SPClientAppDAO saml2SPClientAppDAO;
59
60 public ClientAppLogic(
61 final ServiceOps serviceOps,
62 final ClientAppUtilsFactory clientAppUtilsFactory,
63 final ClientAppDataBinder binder,
64 final CASSPClientAppDAO casSPClientAppDAO,
65 final OIDCRPClientAppDAO oidcRPClientAppDAO,
66 final SAML2SPClientAppDAO saml2SPClientAppDAO) {
67
68 this.serviceOps = serviceOps;
69 this.clientAppUtilsFactory = clientAppUtilsFactory;
70 this.binder = binder;
71 this.casSPClientAppDAO = casSPClientAppDAO;
72 this.oidcRPClientAppDAO = oidcRPClientAppDAO;
73 this.saml2SPClientAppDAO = saml2SPClientAppDAO;
74 }
75
76 @PreAuthorize("hasRole('" + AMEntitlement.CLIENTAPP_LIST + "')")
77 public <T extends ClientAppTO> List<T> list(final ClientAppType type) {
78 Stream<T> stream;
79
80 switch (type) {
81 case OIDCRP:
82 stream = oidcRPClientAppDAO.findAll().stream().map(binder::getClientAppTO);
83 break;
84 case CASSP:
85 stream = casSPClientAppDAO.findAll().stream().map(binder::getClientAppTO);
86 break;
87 case SAML2SP:
88 default:
89 stream = saml2SPClientAppDAO.findAll().stream().map(binder::getClientAppTO);
90 }
91
92 return stream.collect(Collectors.toList());
93 }
94
95 protected void checkType(final ClientAppType type, final ClientAppUtils clientAppUtils) {
96 if (clientAppUtils.getType() != type) {
97 SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidRequest);
98 sce.getElements().add("Found " + type + ", expected " + clientAppUtils.getType());
99 throw sce;
100 }
101 }
102
103 @PreAuthorize("hasRole('" + AMEntitlement.CLIENTAPP_READ + "')")
104 @Transactional(readOnly = true)
105 public <T extends ClientAppTO> T read(final ClientAppType type, final String key) {
106 switch (type) {
107 case OIDCRP:
108 OIDCRPClientApp oidcrp = oidcRPClientAppDAO.find(key);
109 if (oidcrp == null) {
110 throw new NotFoundException("Client app " + key + " not found");
111 }
112
113 checkType(type, clientAppUtilsFactory.getInstance(oidcrp));
114
115 return binder.getClientAppTO(oidcrp);
116 case CASSP:
117 CASSPClientApp cassp = casSPClientAppDAO.find(key);
118 if (cassp == null) {
119 throw new NotFoundException("Client app " + key + " not found");
120 }
121
122 checkType(type, clientAppUtilsFactory.getInstance(cassp));
123
124 return binder.getClientAppTO(cassp);
125 case SAML2SP:
126 default:
127 SAML2SPClientApp saml2sp = saml2SPClientAppDAO.find(key);
128 if (saml2sp == null) {
129 throw new NotFoundException("Client app " + key + " not found");
130 }
131
132 checkType(type, clientAppUtilsFactory.getInstance(saml2sp));
133
134 return binder.getClientAppTO(saml2sp);
135 }
136 }
137
138 @PreAuthorize("hasRole('" + AMEntitlement.CLIENTAPP_CREATE + "')")
139 public <T extends ClientAppTO> T create(final ClientAppType type, final ClientAppTO clientAppTO) {
140 checkType(type, clientAppUtilsFactory.getInstance(clientAppTO));
141
142 switch (type) {
143 case OIDCRP:
144 return binder.getClientAppTO(oidcRPClientAppDAO.save(binder.create(clientAppTO)));
145 case CASSP:
146 return binder.getClientAppTO(casSPClientAppDAO.save(binder.create(clientAppTO)));
147 case SAML2SP:
148 default:
149 return binder.getClientAppTO(saml2SPClientAppDAO.save(binder.create(clientAppTO)));
150 }
151 }
152
153 @PreAuthorize("hasRole('" + AMEntitlement.CLIENTAPP_UPDATE + "')")
154 public <T extends ClientAppTO> T update(final ClientAppType type, final ClientAppTO clientAppTO) {
155 checkType(type, clientAppUtilsFactory.getInstance(clientAppTO));
156
157 switch (type) {
158 case OIDCRP:
159 OIDCRPClientApp oidcrp = oidcRPClientAppDAO.find(clientAppTO.getKey());
160 if (oidcrp == null) {
161 throw new NotFoundException("Client app " + clientAppTO.getKey() + " not found");
162 }
163 binder.update(oidcrp, clientAppTO);
164 return binder.getClientAppTO(oidcRPClientAppDAO.save(oidcrp));
165 case CASSP:
166 CASSPClientApp cassp = casSPClientAppDAO.find(clientAppTO.getKey());
167 if (cassp == null) {
168 throw new NotFoundException("Client app " + clientAppTO.getKey() + " not found");
169 }
170 binder.update(cassp, clientAppTO);
171 return binder.getClientAppTO(casSPClientAppDAO.save(cassp));
172 case SAML2SP:
173 default:
174 SAML2SPClientApp saml2sp = saml2SPClientAppDAO.find(clientAppTO.getKey());
175 if (saml2sp == null) {
176 throw new NotFoundException("Client app " + clientAppTO.getKey() + " not found");
177 }
178 binder.update(saml2sp, clientAppTO);
179 return binder.getClientAppTO(saml2SPClientAppDAO.save(saml2sp));
180 }
181 }
182
183 @PreAuthorize("hasRole('" + AMEntitlement.CLIENTAPP_DELETE + "')")
184 public <T extends ClientAppTO> T delete(final ClientAppType type, final String key) {
185 final T deleted;
186 switch (type) {
187 case OIDCRP:
188 OIDCRPClientApp oidcrp = oidcRPClientAppDAO.find(key);
189 if (oidcrp == null) {
190 throw new NotFoundException("Client app " + key + " not found");
191 }
192 oidcRPClientAppDAO.delete(oidcrp);
193 deleted = binder.getClientAppTO(oidcrp);
194 break;
195 case CASSP:
196 CASSPClientApp cassp = casSPClientAppDAO.find(key);
197 if (cassp == null) {
198 throw new NotFoundException("Client app " + key + " not found");
199 }
200 casSPClientAppDAO.delete(cassp);
201 deleted = binder.getClientAppTO(cassp);
202 break;
203 case SAML2SP:
204 default:
205 SAML2SPClientApp saml2sp = saml2SPClientAppDAO.find(key);
206 if (saml2sp == null) {
207 throw new NotFoundException("Client app " + key + " not found");
208 }
209 saml2SPClientAppDAO.delete(saml2sp);
210 deleted = binder.getClientAppTO(saml2sp);
211 }
212
213 return deleted;
214 }
215
216 @Override
217 protected ClientAppTO resolveReference(final Method method, final Object... args)
218 throws UnresolvedReferenceException {
219
220 if (ArrayUtils.isEmpty(args) || args.length != 2) {
221 throw new UnresolvedReferenceException();
222 }
223
224 try {
225 final String key;
226 final ClientAppType type;
227
228 if (args[0] instanceof ClientAppType) {
229 type = (ClientAppType) args[0];
230 } else {
231 throw new RuntimeException("Invalid ClientApp type");
232 }
233
234 if (args[1] instanceof String) {
235 key = (String) args[1];
236 } else if (args[1] instanceof ClientAppTO) {
237 key = ((ClientAppTO) args[1]).getKey();
238 } else {
239 throw new RuntimeException("Invalid ClientApp key");
240 }
241
242 final ClientApp clientApp;
243 switch (type) {
244 case CASSP:
245 clientApp = casSPClientAppDAO.find(key);
246 break;
247 case SAML2SP:
248 clientApp = saml2SPClientAppDAO.find(key);
249 break;
250 case OIDCRP:
251 clientApp = oidcRPClientAppDAO.find(key);
252 break;
253 default:
254 throw new RuntimeException("Unexpected ClientApp type");
255 }
256
257 return binder.getClientAppTO(clientApp);
258 } catch (Throwable t) {
259 throw new UnresolvedReferenceException();
260 }
261 }
262 }