2020import org .slf4j .LoggerFactory ;
2121
2222import java .util .*;
23+ import java .util .regex .Pattern ;
2324import java .util .stream .Collectors ;
2425
2526import 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