Skip to content

Commit b9b4443

Browse files
committed
add link-id-regex field to services
1 parent 430af4b commit b9b4443

File tree

4 files changed

+247
-59
lines changed

4 files changed

+247
-59
lines changed

src/main/java/com/uid2/admin/vertx/Endpoints.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ public enum Endpoints {
8282
API_SERVICE_ADD("/api/service/add"),
8383
API_SERVICE_UPDATE("/api/service/update"),
8484
API_SERVICE_DELETE("/api/service/delete"),
85+
API_SERVICE_REMOVE_LINK_ID_REGEX("/api/service/remove-link-id-regex"),
8586

8687
API_SHARING_LISTS("/api/sharing/lists"),
8788
API_SHARING_LIST_SITEID("/api/sharing/list/:siteId"),

src/main/java/com/uid2/admin/vertx/service/ServiceService.java

Lines changed: 93 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.slf4j.LoggerFactory;
2121

2222
import java.util.*;
23+
import java.util.regex.Pattern;
2324
import java.util.stream.Collectors;
2425

2526
import static com.uid2.admin.vertx.Endpoints.*;
@@ -67,6 +68,11 @@ public void setupRoutes(Router router) {
6768
this.handleDelete(ctx);
6869
}
6970
}, new AuditParams(Collections.emptyList(), List.of("service_id")), Role.SUPER_USER));
71+
router.post(API_SERVICE_REMOVE_LINK_ID_REGEX.toString()).blockingHandler(auth.handle((ctx) -> {
72+
synchronized (writeLock) {
73+
this.handleRemoveLinkIdRegex(ctx);
74+
}
75+
}, new AuditParams(Collections.emptyList(), List.of("service_id")), Role.PRIVILEGED));
7076
}
7177

7278
private void handleServiceListAll(RoutingContext rc) {
@@ -113,6 +119,7 @@ private void handleServiceAdd(RoutingContext rc) {
113119
Integer siteId = body.getInteger("site_id");
114120
String name = body.getString("name");
115121
JsonArray rolesSpec = body.getJsonArray("roles");
122+
String linkIdRegex = body.getString("link_id_regex");
116123
if (siteId == null || name == null || rolesSpec == null || rolesSpec.isEmpty()) {
117124
ResponseUtil.error(rc, 400, "required parameters: site_id, name, roles");
118125
return;
@@ -147,11 +154,22 @@ private void handleServiceAdd(RoutingContext rc) {
147154
return;
148155
}
149156

157+
if (linkIdRegex != null && !linkIdRegex.isEmpty() && !linkIdRegex.isBlank()) {
158+
try {
159+
Pattern.compile(linkIdRegex);
160+
} catch (Exception e) {
161+
ResponseUtil.error(rc, 400, "invalid parameter: link_id_regex; not a valid regex");
162+
return;
163+
}
164+
} else {
165+
linkIdRegex = null;
166+
}
167+
150168
final List<Service> services = this.serviceProvider.getAllServices()
151169
.stream().sorted(Comparator.comparingInt(Service::getServiceId))
152170
.collect(Collectors.toList());
153171
final int serviceId = 1 + services.stream().mapToInt(Service::getServiceId).max().orElse(0);
154-
Service service = new Service(serviceId, siteId, name, roles);
172+
Service service = new Service(serviceId, siteId, name, roles, linkIdRegex);
155173

156174
services.add(service);
157175

@@ -163,20 +181,20 @@ private void handleServiceAdd(RoutingContext rc) {
163181
}
164182
}
165183

166-
// Can update the site_id, name and roles
184+
// Can update the site_id, name, roles, and link_id_regex
167185
private void handleUpdate(RoutingContext rc) {
168186
try {
169-
JsonObject body = rc.body().asJsonObject();
170-
if (body == null) {
171-
ResponseUtil.error(rc, 400, "json payload required but not provided");
172-
return;
173-
}
174-
Integer serviceId = body.getInteger("service_id");
175-
Integer siteId = body.getInteger("site_id");
176-
String name = body.getString("name");
187+
JsonObject body = rc.body() != null ? rc.body().asJsonObject() : null;
188+
Service service = findServiceFromRequest(rc);
189+
if (service == null) return; // error already handled
190+
191+
192+
Integer siteId = body != null ? body.getInteger("site_id") : null;
193+
String name = body != null ? body.getString("name") : null;
194+
String linkIdRegex = body != null ? body.getString("link_id_regex") : null;
177195

178196
JsonArray rolesSpec = null;
179-
if (body.getString("roles") != null && !body.getString("roles").isEmpty()) {
197+
if (body != null && body.getString("roles") != null && !body.getString("roles").isEmpty()) {
180198
try {
181199
rolesSpec = body.getJsonArray("roles");
182200
} catch (ClassCastException c) {
@@ -185,16 +203,7 @@ private void handleUpdate(RoutingContext rc) {
185203
}
186204
}
187205

188-
if (serviceId == null) {
189-
ResponseUtil.error(rc, 400, "required parameters: service_id");
190-
return;
191-
}
192-
193-
final Service service = serviceProvider.getService(serviceId);
194-
if (service == null) {
195-
ResponseUtil.error(rc, 404, "failed to find a service for service_id: " + serviceId);
196-
return;
197-
}
206+
int serviceId = service.getServiceId();
198207

199208
// check that this does not create a duplicate service
200209
if (siteHasService(siteId, name, serviceId)) {
@@ -226,6 +235,16 @@ private void handleUpdate(RoutingContext rc) {
226235
service.setRoles(roles);
227236
}
228237

238+
if (linkIdRegex != null && !linkIdRegex.isEmpty() && !linkIdRegex.isBlank()) {
239+
try {
240+
Pattern.compile(linkIdRegex);
241+
service.setLinkIdRegex(linkIdRegex);
242+
} catch (Exception e) {
243+
ResponseUtil.error(rc, 400, "invalid parameter: link_id_regex; not a valid regex");
244+
return;
245+
}
246+
}
247+
229248
if (siteId != null && siteId != 0) {
230249
service.setSiteId(siteId);
231250
}
@@ -234,10 +253,7 @@ private void handleUpdate(RoutingContext rc) {
234253
service.setName(name);
235254
}
236255

237-
final List<Service> services = this.serviceProvider.getAllServices()
238-
.stream().sorted(Comparator.comparingInt(Service::getServiceId))
239-
.collect(Collectors.toList());
240-
256+
List<Service> services = getSortedServices();
241257

242258
storeWriter.upload(services, null);
243259

@@ -248,40 +264,31 @@ private void handleUpdate(RoutingContext rc) {
248264
}
249265

250266
private void handleDelete(RoutingContext rc) {
251-
final int serviceId;
252-
JsonObject body = rc.body() != null ? rc.body().asJsonObject() : null;
253-
if (body == null) {
254-
ResponseUtil.error(rc, 400, "json payload required but not provided");
255-
return;
256-
}
257-
serviceId = body.getInteger("service_id", -1);
258-
if (serviceId == -1) {
259-
ResponseUtil.error(rc, 400, "required parameters: service_id");
260-
return;
261-
}
267+
Service service = findServiceFromRequest(rc);
268+
if (service == null) return; // error already handled
262269

263270
try {
264-
serviceProvider.loadContent();
265-
266-
Service service = serviceProvider.getService(serviceId);
267-
if (service == null) {
268-
ResponseUtil.error(rc, 404, "failed to find a service for service_id: " + serviceId);
269-
return;
270-
}
271-
272-
final List<Service> services = this.serviceProvider.getAllServices()
273-
.stream().sorted(Comparator.comparingInt(Service::getServiceId))
274-
.collect(Collectors.toList());
275-
271+
List<Service> services = getSortedServices();
276272
services.remove(service);
277-
278273
storeWriter.upload(services, null);
279-
280274
rc.response().end(toJson(service).encodePrettily());
281275
} catch (Exception e) {
282276
ResponseUtil.errorInternal(rc, "Internal Server Error", e);
283277
}
278+
}
279+
280+
private void handleRemoveLinkIdRegex(RoutingContext rc) {
281+
Service service = findServiceFromRequest(rc);
282+
if (service == null) return; // error already handled
284283

284+
try {
285+
service.setLinkIdRegex(null);
286+
List<Service> services = getSortedServices();
287+
storeWriter.upload(services, null);
288+
rc.response().end(toJson(service).encodePrettily());
289+
} catch (Exception e) {
290+
ResponseUtil.errorInternal(rc, "Internal Server Error", e);
291+
}
285292
}
286293

287294
private JsonObject toJson(Service s) {
@@ -290,6 +297,7 @@ private JsonObject toJson(Service s) {
290297
jsonObject.put("site_id", s.getSiteId());
291298
jsonObject.put("name", s.getName());
292299
jsonObject.put("roles", s.getRoles());
300+
jsonObject.put("link_id_regex", s.getLinkIdRegex());
293301
return jsonObject;
294302
}
295303

@@ -302,4 +310,39 @@ private boolean siteHasService(Integer siteId, String name, int serviceId) {
302310
&& serviceProvider.getAllServices().stream().anyMatch(s -> s.getServiceId() != serviceId
303311
&& s.getSiteId() == siteId && s.getName().equals(name));
304312
}
313+
314+
315+
private Service findServiceFromRequest(RoutingContext rc) {
316+
JsonObject body = rc.body() != null ? rc.body().asJsonObject() : null;
317+
if (body == null) {
318+
ResponseUtil.error(rc, 400, "json payload required but not provided");
319+
return null;
320+
}
321+
322+
int serviceId = body.getInteger("service_id", -1);
323+
if (serviceId == -1) {
324+
ResponseUtil.error(rc, 400, "required parameters: service_id");
325+
return null;
326+
}
327+
328+
try {
329+
serviceProvider.loadContent();
330+
Service service = serviceProvider.getService(serviceId);
331+
if (service == null) {
332+
ResponseUtil.error(rc, 404, "failed to find a service for service_id: " + serviceId);
333+
return null;
334+
}
335+
return service;
336+
} catch (Exception e) {
337+
ResponseUtil.errorInternal(rc, "Internal Server Error", e);
338+
return null;
339+
}
340+
}
341+
342+
private List<Service> getSortedServices() {
343+
return serviceProvider.getAllServices()
344+
.stream()
345+
.sorted(Comparator.comparingInt(Service::getServiceId))
346+
.collect(Collectors.toList());
347+
}
305348
}

0 commit comments

Comments
 (0)