Skip to content

Commit 6702b03

Browse files
committed
UY-1571 add clear scheduled operation
1 parent decbc19 commit 6702b03

8 files changed

Lines changed: 129 additions & 14 deletions

File tree

console/src/main/java/io/imunity/console/views/directory_browser/identities/ChangeEntityStateHandler.java

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,20 @@
44
*/
55
package io.imunity.console.views.directory_browser.identities;
66

7+
import java.util.Set;
8+
9+
import org.springframework.stereotype.Component;
10+
711
import com.vaadin.flow.component.icon.VaadinIcon;
12+
813
import io.imunity.console.views.directory_browser.EntityWithLabel;
914
import io.imunity.vaadin.elements.NotificationPresenter;
1015
import io.imunity.vaadin.elements.grid.SingleActionHandler;
11-
12-
import org.springframework.stereotype.Component;
1316
import pl.edu.icm.unity.base.entity.EntityInformation;
1417
import pl.edu.icm.unity.base.entity.EntityParam;
15-
import pl.edu.icm.unity.base.entity.EntityState;
1618
import pl.edu.icm.unity.base.message.MessageSource;
1719
import pl.edu.icm.unity.engine.api.EntityManagement;
1820

19-
import java.util.Set;
20-
2121
@Component
2222
class ChangeEntityStateHandler
2323
{
@@ -57,9 +57,7 @@ private boolean setEntityStatus(long entityId, EntityInformation newState,
5757
try
5858
{
5959
EntityParam entity = new EntityParam(entityId);
60-
61-
if (newState.getState() != EntityState.onlyLoginPermitted)
62-
identitiesMan.setEntityStatus(entity, newState.getState());
60+
identitiesMan.setEntityStatus(entity, newState.getState());
6361
identitiesMan.scheduleEntityChange(entity, newState.getScheduledOperationTime(),
6462
newState.getScheduledOperation());
6563
refreshCallback.run();

documentation/src/main/rest-api/rest-api-v1.txt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -858,15 +858,22 @@ allowed to be called on self .
858858
Schedules an operation to be invoked at a given time on an entity. Must be called by privileged user. Allowed
859859
operations are: +REMOVE+ and +DISABLE+.
860860

861+
=== Clear scheduled entity operations
862+
863+
+@Path("/entity/{entityId}/admin-schedule")+ +
864+
+@QueryParam("identityType")+ +
865+
+@DELETE+ +
866+
867+
Deletes all scheduled operations. Additionally, if the entity is in the +onlyLoginPermitted+ state, it sets the new status to +valid+.
868+
861869

862870
=== Change entity status
863871

864872
+@Path("/entity/{entityId}/status/{status}")+ +
865873
+@QueryParam("identityType")+ +
866874
+@PUT+ +
867875

868-
Changes the status of an entity. Change of the status can cancel a scheduled operation (like account removal)
869-
if one is present. Allowed statuses: +valid+, +authenticationDisabled+, and +disabled+.
876+
Changes the status of an entity. Allowed statuses: +valid+, +authenticationDisabled+, and +disabled+.
870877

871878

872879
=== Remove identity

engine-api/src/main/java/pl/edu/icm/unity/engine/api/EntityManagement.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,13 @@ void scheduleEntityChange(EntityParam toChange, Date changeTime, EntityScheduled
127127
*/
128128
void scheduleRemovalByUser(EntityParam toChange, Date changeTime) throws EngineException;
129129

130+
/**
131+
* If entity is in the state {@link EntityState#onlyLoginPermitted} this method clears the
132+
* removal of the entity: state is set to enabled and user ordered removal is removed.
133+
* Requires only the attributeModify capability (allowed for selfAccess).
134+
*/
135+
void clearScheduledRemovalStatus(EntityParam toChange) throws EngineException;
136+
130137
Map<Long, List<Identity>> getIdentitiesForEntities(Set<Long> entityIds);
131138

132139
/**

engine/src/main/java/pl/edu/icm/unity/engine/identity/EntityManagementImpl.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -632,10 +632,6 @@ public void setEntityStatus(EntityParam toChange, EntityState status)
632632
throws EngineException
633633
{
634634
toChange.validateInitialization();
635-
if (status == EntityState.onlyLoginPermitted)
636-
throw new IllegalArgumentException("The new entity status 'only login permitted' "
637-
+ "can be only set as a side effect of scheduling an account "
638-
+ "removal with a grace period.");
639635
long entityId = idResolver.getEntityId(toChange);
640636
authz.checkAuthorization(authz.isSelf(entityId), AuthzCapability.identityModify);
641637
EntityInformation current = entityDAO.getByKey(entityId);
@@ -841,6 +837,15 @@ public void scheduleRemovalByUser(EntityParam toChange, Date changeTime)
841837
scheduledOperationHelper.setScheduledRemovalByUser(entityId, changeTime);
842838
}
843839

840+
@Override
841+
@Transactional
842+
public void clearScheduledRemovalStatus(EntityParam toChange) throws EngineException
843+
{
844+
toChange.validateInitialization();
845+
long entityId = idResolver.getEntityId(toChange);
846+
authz.checkAuthorization(authz.isSelf(entityId), AuthzCapability.attributeModify);
847+
scheduledOperationHelper.clearScheduledRemovalStatus(entityId);
848+
}
844849

845850
@Override
846851
@Transactional

engine/src/test/java/pl/edu/icm/unity/engine/identity/TestIdentities.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,17 @@ public void disabledStatusIsReturned() throws Exception
421421
assertEquals(EntityState.disabled, entity.getState());
422422
}
423423

424+
@Test
425+
public void shouldSetOnlyLoginPermitedStatus() throws Exception
426+
{
427+
IdentityParam idParam = new IdentityParam(X500Identity.ID, "CN=golbi");
428+
Identity id = idsMan.addEntity(idParam, "crMock", EntityState.valid);
429+
430+
idsMan.setEntityStatus(new EntityParam(id), EntityState.onlyLoginPermitted);
431+
432+
Entity entity = idsMan.getEntity(new EntityParam(id));
433+
assertEquals(EntityState.onlyLoginPermitted, entity.getState());
434+
}
424435

425436
@Test
426437
public void shouldFailToAddToSubgoupWhenNotInParent() throws Exception

engine/src/test/java/pl/edu/icm/unity/engine/identity/TestIdentitiesWithPassword.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import static org.junit.jupiter.api.Assertions.assertEquals;
1010
import static org.junit.jupiter.api.Assertions.assertFalse;
11+
import static org.junit.jupiter.api.Assertions.assertNull;
1112
import static org.junit.jupiter.api.Assertions.assertTrue;
1213
import static org.junit.jupiter.api.Assertions.fail;
1314

@@ -79,6 +80,21 @@ public void scheduledRemovalWorksForUser() throws Exception
7980
}
8081
}
8182

83+
@Test
84+
public void shouldClearScheduledRemovalAndSetStatusToValid() throws Exception
85+
{
86+
Identity id = createUsernameUserWithRole(InternalAuthorizationManagerImpl.USER_ROLE);
87+
EntityParam ep1 = new EntityParam(id.getEntityId());
88+
89+
setupUserContext(DEF_USER, null);
90+
91+
idsMan.scheduleRemovalByUser(ep1, new Date(System.currentTimeMillis()+200));
92+
idsMan.clearScheduledRemovalStatus(ep1);
93+
Entity entity = idsMan.getEntity(ep1);
94+
assertEquals(EntityState.valid, entity.getState());
95+
assertNull(entity.getEntityInformation().getScheduledOperationTime());
96+
}
97+
8298
@Test
8399
public void scheduledRemovalWorksForUserImmediately() throws Exception
84100
{

rest-admin/src/main/java/pl/edu/icm/unity/restadm/RESTAdmin.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,23 @@ public void scheduleOperation(@PathParam("entityId") String entityId, @QueryPara
276276
identitiesMan.scheduleEntityChange(getEP(entityId, idType), time, operation);
277277
}
278278

279+
@Path("/entity/{entityId}/admin-schedule")
280+
@DELETE
281+
public void clearScheduledOperation(@PathParam("entityId") String entityId, @QueryParam("identityType") String idType)
282+
throws EngineException
283+
{
284+
log.info("clear scheduleEntityChange of " + entityId );
285+
286+
EntityParam ep = getEP(entityId, idType);
287+
Entity entity = identitiesMan.getEntity(ep);
288+
if (entity.getState().equals(EntityState.onlyLoginPermitted))
289+
{
290+
identitiesMan.clearScheduledRemovalStatus(ep);
291+
}
292+
293+
identitiesMan.scheduleEntityChange(ep, null, null);
294+
}
295+
279296
@Path("/entity/{entityId}/status/{status}")
280297
@PUT
281298
public void changeEntityStatus(@PathParam("entityId") String entityId, @PathParam("status") String status,

rest-admin/src/test/java/pl/edu/icm/unity/restadm/TestWrite.java

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,60 @@ public void scheduleOperationByAdminWorks() throws Exception
302302
assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getCode());
303303
}
304304
}
305+
306+
@Test
307+
public void shouldClearScheduledOperation() throws Exception
308+
{
309+
HttpPost addEntity = new HttpPost("/restadm/v1/entity/identity/userName/userA?credentialRequirement=cr-pass");
310+
String contents = executeQuery(addEntity);
311+
ObjectNode root = (ObjectNode) m.readTree(contents);
312+
long entityId = root.get("entityId").asLong();
313+
assertTrue(checkIdentity("userA"));
314+
System.out.println("Added entity:\n" + contents);
315+
316+
long time = System.currentTimeMillis() + 20000;
317+
HttpPut scheduleRemoval = new HttpPut("/restadm/v1/entity/" + entityId + "/admin-schedule?when=" +
318+
time + "&operation=REMOVE");
319+
try(ClassicHttpResponse response = client.executeOpen(host, scheduleRemoval, getClientContext(host))){
320+
assertEquals(Status.NO_CONTENT.getStatusCode(), response.getCode());
321+
}
322+
323+
HttpDelete clearSchedule = new HttpDelete("/restadm/v1/entity/" + entityId + "/admin-schedule");
324+
try(ClassicHttpResponse response = client.executeOpen(host, clearSchedule, getClientContext(host))){
325+
assertEquals(Status.NO_CONTENT.getStatusCode(), response.getCode());
326+
}
327+
328+
Entity entity = idsMan.getEntity(new EntityParam(entityId));
329+
assertEquals(null, entity.getEntityInformation().getScheduledOperationTime());
330+
assertEquals(null, entity.getEntityInformation().getScheduledOperation());
331+
}
332+
333+
@Test
334+
public void shouldClearRemovalByUserTime() throws Exception
335+
{
336+
HttpPost addEntity = new HttpPost("/restadm/v1/entity/identity/userName/userA?credentialRequirement=cr-pass");
337+
String contents = executeQuery(addEntity);
338+
ObjectNode root = (ObjectNode) m.readTree(contents);
339+
long entityId = root.get("entityId").asLong();
340+
assertTrue(checkIdentity("userA"));
341+
System.out.println("Added entity:\n" + contents);
342+
343+
long time = System.currentTimeMillis() + 20000;
344+
HttpPut removalSchedule = new HttpPut("/restadm/v1/entity/" + entityId + "/removal-schedule?when=" +
345+
time);
346+
try(ClassicHttpResponse response = client.executeOpen(host, removalSchedule, getClientContext(host))){
347+
assertEquals(Status.NO_CONTENT.getStatusCode(), response.getCode());
348+
}
349+
350+
HttpDelete clearSchedule = new HttpDelete("/restadm/v1/entity/" + entityId + "/admin-schedule");
351+
try(ClassicHttpResponse response = client.executeOpen(host, clearSchedule, getClientContext(host))){
352+
assertEquals(Status.NO_CONTENT.getStatusCode(), response.getCode());
353+
}
354+
355+
Entity entity = idsMan.getEntity(new EntityParam(entityId));
356+
assertEquals(EntityState.valid, entity.getEntityInformation().getState());
357+
assertEquals(null, entity.getEntityInformation().getRemovalByUserTime());
358+
}
305359

306360
@Test
307361
public void scheduleRemovalByUserWorks() throws Exception

0 commit comments

Comments
 (0)