Skip to content

Commit 583587c

Browse files
authored
Merge pull request #536 from IABTechLab/ian-UID2-2084-add-disable-service-service-link
add disabled field to services and service links
2 parents 9c900fb + 46760d9 commit 583587c

File tree

7 files changed

+150
-18
lines changed

7 files changed

+150
-18
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<!-- check micrometer.version vertx-micrometer-metrics consumes before bumping up -->
1717
<micrometer.version>1.12.2</micrometer.version>
1818
<junit-jupiter.version>5.11.2</junit-jupiter.version>
19-
<uid2-shared.version>10.7.14</uid2-shared.version>
19+
<uid2-shared.version>10.8.0</uid2-shared.version>
2020
<okta-jwt.version>0.5.10</okta-jwt.version>
2121
<image.version>${project.version}</image.version>
2222
</properties>

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ private void handleServiceLinkUpdate(RoutingContext rc) {
162162
Integer siteId = body.getInteger("site_id");
163163
String name = body.getString("name");
164164
JsonArray rolesJson = body.getJsonArray("roles");
165+
Boolean disabled = body.getBoolean("disabled");
165166

166167
if (siteId == null || serviceId == null || linkId == null || linkId.isEmpty()) {
167168
ResponseUtil.error(rc, 400, "required parameters: site_id, service_id, link_id");
@@ -195,6 +196,10 @@ private void handleServiceLinkUpdate(RoutingContext rc) {
195196
serviceLink.setName(name);
196197
}
197198

199+
if (disabled != null) {
200+
serviceLink.setDisabled(disabled);
201+
}
202+
198203
if (rolesJson != null && !rolesJson.isEmpty()) {
199204
final Set<Role> roles;
200205
try {
@@ -259,6 +264,7 @@ private JsonObject toJson(ServiceLink s) {
259264
jsonObject.put("site_id", s.getSiteId());
260265
jsonObject.put("name", s.getName());
261266
jsonObject.put("roles", s.getRoles());
267+
jsonObject.put("disabled", s.isDisabled());
262268
return jsonObject;
263269
}
264270

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ private void handleUpdate(RoutingContext rc) {
191191
Integer siteId = body.getInteger("site_id");
192192
String name = body.getString("name");
193193
String linkIdRegex = body.getString("link_id_regex");
194+
Boolean disabled = body.getBoolean("disabled");
194195

195196
JsonArray rolesSpec = null;
196197
if (body.getString("roles") != null && !body.getString("roles").isEmpty()) {
@@ -242,6 +243,10 @@ private void handleUpdate(RoutingContext rc) {
242243
service.setLinkIdRegex(linkIdRegex);
243244
}
244245

246+
if (disabled != null) {
247+
service.setDisabled(disabled);
248+
}
249+
245250
if (siteId != null && siteId != 0) {
246251
service.setSiteId(siteId);
247252
}
@@ -295,6 +300,7 @@ private JsonObject toJson(Service s) {
295300
jsonObject.put("name", s.getName());
296301
jsonObject.put("roles", s.getRoles());
297302
jsonObject.put("link_id_regex", s.getLinkIdRegex());
303+
jsonObject.put("disabled", s.isDisabled());
298304
return jsonObject;
299305
}
300306

src/test/java/com/uid2/admin/vertx/ServiceLinkServiceTest.java

Lines changed: 72 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import io.vertx.junit5.VertxTestContext;
1414
import org.junit.jupiter.api.Test;
1515
import org.junit.jupiter.params.ParameterizedTest;
16+
import org.junit.jupiter.params.provider.Arguments;
1617
import org.junit.jupiter.params.provider.MethodSource;
1718
import org.junit.jupiter.params.provider.ValueSource;
1819

@@ -387,6 +388,34 @@ void updateServiceLink_updateNameOnly_succeeds(Vertx vertx, VertxTestContext tes
387388
});
388389
}
389390

391+
@Test
392+
void updateServiceLink_updateDisabledOnly_succeeds(Vertx vertx, VertxTestContext testContext) {
393+
fakeAuth(Role.MAINTAINER);
394+
395+
setSites(new Site(123, "name1", false));
396+
setServices(new Service(1, 123, "name1", Set.of(Role.MAINTAINER, Role.MAPPER)));
397+
ServiceLink existingLink = new ServiceLink("link1", 1, 123, "name1", Set.of(Role.MAPPER));
398+
setServiceLinks(existingLink);
399+
400+
JsonObject jo = new JsonObject();
401+
jo.put("link_id", "link1");
402+
jo.put("service_id", 1);
403+
jo.put("site_id", 123);
404+
jo.put("disabled", true);
405+
406+
ServiceLink expected = new ServiceLink("link1", 1, 123, "name1", Set.of(Role.MAPPER));
407+
expected.setDisabled(true);
408+
409+
post(vertx, testContext, "api/service_link/update", jo.encode(), response -> {
410+
assertEquals(200, response.statusCode());
411+
checkServiceLinkJson(expected, response.bodyAsJsonObject());
412+
verify(serviceStoreWriter, never()).upload(null, null);
413+
verify(serviceLinkStoreWriter, times(1)).upload(List.of(expected), null);
414+
415+
testContext.completeNow();
416+
});
417+
}
418+
390419
@Test
391420
void updateServiceLink_updateRoleOnly_succeeds(Vertx vertx, VertxTestContext testContext) {
392421
fakeAuth(Role.MAINTAINER);
@@ -442,6 +471,35 @@ void updateServiceLink_updateRoleAndName_succeeds(Vertx vertx, VertxTestContext
442471
});
443472
}
444473

474+
@Test
475+
void updateServiceLink_updateRoleNameDisabled_succeeds(Vertx vertx, VertxTestContext testContext) {
476+
fakeAuth(Role.MAINTAINER);
477+
478+
setSites(new Site(123, "name1", false));
479+
setServices(new Service(1, 123, "name1", Set.of(Role.MAINTAINER, Role.MAPPER, Role.SHARER)));
480+
ServiceLink existingLink = new ServiceLink("link1", 1, 123, "name1", Set.of(Role.MAPPER));
481+
setServiceLinks(existingLink);
482+
483+
JsonObject jo = new JsonObject();
484+
jo.put("link_id", "link1");
485+
jo.put("service_id", 1);
486+
jo.put("site_id", 123);
487+
jo.put("name", "newname");
488+
jo.put("roles", JsonArray.of(Role.MAPPER, Role.SHARER));
489+
jo.put("disabled", true);
490+
491+
ServiceLink expected = new ServiceLink("link1", 1, 123, "newname", Set.of(Role.MAPPER, Role.SHARER), true);
492+
493+
post(vertx, testContext, "api/service_link/update", jo.encode(), response -> {
494+
assertEquals(200, response.statusCode());
495+
checkServiceLinkJson(expected, response.bodyAsJsonObject());
496+
verify(serviceStoreWriter, never()).upload(null, null);
497+
verify(serviceLinkStoreWriter, times(1)).upload(List.of(expected), null);
498+
499+
testContext.completeNow();
500+
});
501+
}
502+
445503
@Test
446504
void updateServiceLink_roleDoesNotExist_returnsError(Vertx vertx, VertxTestContext testContext) {
447505
fakeAuth(Role.MAINTAINER);
@@ -622,20 +680,20 @@ void addServiceLink_linkIdRegex_validation(String linkIdRegex, String linkId, bo
622680

623681
private static java.util.stream.Stream<org.junit.jupiter.params.provider.Arguments> linkIdRegexCases() {
624682
return java.util.stream.Stream.of(
625-
org.junit.jupiter.params.provider.Arguments.of("link[0-9]+", "invalidLink", false),
626-
org.junit.jupiter.params.provider.Arguments.of("link[0-9]+", "link42", true),
627-
org.junit.jupiter.params.provider.Arguments.of("^[A-Z0-9_]{1,256}$", "XY12345", true), // snowflake valid
628-
org.junit.jupiter.params.provider.Arguments.of("^[A-Z0-9_]{1,256}$", "UID2_ENVIRONMENT", true), // snowflake valid
629-
org.junit.jupiter.params.provider.Arguments.of("^[A-Z0-9_]{1,256}$", "xy12345", false), // snowflake invalid, lowercase
630-
org.junit.jupiter.params.provider.Arguments.of("^[A-Z0-9_]{1,256}$", "X", true), // snowflake valid, minimum length
631-
org.junit.jupiter.params.provider.Arguments.of("^[A-Z0-9_]{1,256}$", "X".repeat(256), true), // snowflake valid, maximum length
632-
org.junit.jupiter.params.provider.Arguments.of("^[A-Z0-9_]{1,256}$", "X".repeat(257), false), // snowflake invalid, exceeds maximum length
633-
org.junit.jupiter.params.provider.Arguments.of("^[A-Z0-9_]{1,256}$", " XY12345", false), // snowflake invalid, leading whitespace
634-
org.junit.jupiter.params.provider.Arguments.of("^[A-Z0-9_]{1,256}$", "XY12345 ", false), // snowflake invalid, trailing whitespace
635-
org.junit.jupiter.params.provider.Arguments.of("^[A-Z0-9_]{1,256}$", "XY 12345", false), // snowflake invalid, whitespace in the middle
636-
org.junit.jupiter.params.provider.Arguments.of("^[A-Z0-9_]{1,256}$", "", false), // snowflake invalid, empty
637-
org.junit.jupiter.params.provider.Arguments.of("^[A-Z0-9_]{1,256}$", " ", false), // snowflake invalid, just whitespace
638-
org.junit.jupiter.params.provider.Arguments.of("^[A-Z0-9_]{1,256}$", "XY_12345", true) // snowflake valid, used underscore
683+
Arguments.of("link[0-9]+", "invalidLink", false),
684+
Arguments.of("link[0-9]+", "link42", true),
685+
Arguments.of("^[A-Z0-9_]{1,256}$", "XY12345", true), // snowflake valid
686+
Arguments.of("^[A-Z0-9_]{1,256}$", "UID2_ENVIRONMENT", true), // snowflake valid
687+
Arguments.of("^[A-Z0-9_]{1,256}$", "xy12345", false), // snowflake invalid, lowercase
688+
Arguments.of("^[A-Z0-9_]{1,256}$", "X", true), // snowflake valid, minimum length
689+
Arguments.of("^[A-Z0-9_]{1,256}$", "X".repeat(256), true), // snowflake valid, maximum length
690+
Arguments.of("^[A-Z0-9_]{1,256}$", "X".repeat(257), false), // snowflake invalid, exceeds maximum length
691+
Arguments.of("^[A-Z0-9_]{1,256}$", " XY12345", false), // snowflake invalid, leading whitespace
692+
Arguments.of("^[A-Z0-9_]{1,256}$", "XY12345 ", false), // snowflake invalid, trailing whitespace
693+
Arguments.of("^[A-Z0-9_]{1,256}$", "XY 12345", false), // snowflake invalid, whitespace in the middle
694+
Arguments.of("^[A-Z0-9_]{1,256}$", "", false), // snowflake invalid, empty
695+
Arguments.of("^[A-Z0-9_]{1,256}$", " ", false), // snowflake invalid, just whitespace
696+
Arguments.of("^[A-Z0-9_]{1,256}$", "XY_12345", true) // snowflake valid, used underscore
639697
);
640698
}
641699
}

src/test/java/com/uid2/admin/vertx/ServiceServiceTest.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,26 @@ void updateName(Vertx vertx, VertxTestContext testContext) {
580580
});
581581
}
582582

583+
@Test
584+
void updateDisabled(Vertx vertx, VertxTestContext testContext) {
585+
fakeAuth(Role.PRIVILEGED);
586+
587+
Service existingService = new Service(1, 123, "name1", Set.of(Role.MAINTAINER));
588+
setServices(existingService);
589+
590+
JsonObject jo = new JsonObject();
591+
jo.put("service_id", 1);
592+
jo.put("disabled", true);
593+
594+
post(vertx, testContext, "api/service/update", jo.encode(), response -> {
595+
assertEquals(200, response.statusCode());
596+
existingService.setDisabled(true);
597+
checkServiceJson(existingService, response.bodyAsJsonObject());
598+
verify(serviceStoreWriter, times(1)).upload(List.of(existingService), null);
599+
testContext.completeNow();
600+
});
601+
}
602+
583603
@Test
584604
void updateSiteId(Vertx vertx, VertxTestContext testContext) {
585605
fakeAuth(Role.PRIVILEGED);
@@ -600,6 +620,32 @@ void updateSiteId(Vertx vertx, VertxTestContext testContext) {
600620
});
601621
}
602622

623+
@Test
624+
void updateNameDisabledSiteIdRoles(Vertx vertx, VertxTestContext testContext) {
625+
fakeAuth(Role.PRIVILEGED);
626+
627+
Service existingService = new Service(1, 123, "name1", Set.of(Role.MAINTAINER));
628+
setServices(existingService);
629+
630+
JsonObject jo = new JsonObject();
631+
jo.put("service_id", 1);
632+
jo.put("site_id", 456);
633+
jo.put("name", "newname");
634+
jo.put("disabled", true);
635+
jo.put("roles", JsonArray.of(Role.MAINTAINER, Role.MAPPER, Role.SHARER));
636+
637+
post(vertx, testContext, "api/service/update", jo.encode(), response -> {
638+
assertEquals(200, response.statusCode());
639+
existingService.setSiteId(456);
640+
existingService.setName("newname");
641+
existingService.setDisabled(true);
642+
existingService.setRoles(Set.of(Role.MAINTAINER, Role.MAPPER, Role.SHARER));
643+
checkServiceJson(existingService, response.bodyAsJsonObject());
644+
verify(serviceStoreWriter, times(1)).upload(List.of(existingService), null);
645+
testContext.completeNow();
646+
});
647+
}
648+
603649
@Test
604650
void updateWithEmptyValues(Vertx vertx, VertxTestContext testContext) {
605651
fakeAuth(Role.PRIVILEGED);

webroot/adm/service-link.html

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ <h1>UID2 Env - Service Link Management</h1>
7575
]
7676
};
7777

78+
const disabledInput = {
79+
name: 'disabled',
80+
label: 'Disable Service Link',
81+
type: 'checkbox'
82+
};
83+
7884
const operationConfig = {
7985
read: [
8086
{
@@ -141,7 +147,8 @@ <h1>UID2 Env - Service Link Management</h1>
141147
serviceIdInput,
142148
siteIdInput,
143149
linkNameInput,
144-
rolesInput
150+
rolesInput,
151+
disabledInput,
145152
],
146153
apiCall: {
147154
method: 'POST',
@@ -156,7 +163,8 @@ <h1>UID2 Env - Service Link Management</h1>
156163
service_id: parseInt(inputs.serviceId),
157164
site_id: parseInt(inputs.siteId),
158165
name: inputs.linkName || '',
159-
roles: rolesArray
166+
roles: rolesArray,
167+
disabled: typeof inputs.disabled === 'boolean' ? inputs.disabled : undefined,
160168
};
161169
}
162170
}

webroot/adm/service.html

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ <h1>UID2 Env - Service Management</h1>
7474
label: 'Link Id Regex'
7575
};
7676

77+
const disabledInput = {
78+
name: 'disabled',
79+
label: 'Disable Service',
80+
type: 'checkbox'
81+
};
82+
7783
const operationConfig = {
7884
read: [
7985
{
@@ -142,7 +148,8 @@ <h1>UID2 Env - Service Management</h1>
142148
{...serviceNameInput, required: false},
143149
{...siteIdInput, required: false},
144150
{...rolesInput, required: false},
145-
linkIdRegexInput
151+
linkIdRegexInput,
152+
disabledInput
146153
],
147154
apiCall: {
148155
method: 'POST',
@@ -157,6 +164,7 @@ <h1>UID2 Env - Service Management</h1>
157164
if (rolesArray.length > 0) payload.roles = rolesArray;
158165

159166
if (inputs.linkIdRegex) payload.link_id_regex = inputs.linkIdRegex;
167+
if (typeof inputs.disabled === 'boolean') payload.disabled = inputs.disabled;
160168
return payload;
161169
}
162170
}

0 commit comments

Comments
 (0)