Skip to content

Commit 7eca9c5

Browse files
author
Jenkins CI
committed
Merge branch 'master' into dev
2 parents 5e5ec09 + a87803d commit 7eca9c5

5 files changed

Lines changed: 113 additions & 40 deletions

File tree

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

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

7+
import static io.imunity.vaadin.elements.CssClassNames.MEDIUM_VAADIN_FORM_ITEM_LABEL;
8+
9+
import java.time.Instant;
10+
import java.time.LocalDateTime;
11+
import java.time.ZoneId;
12+
import java.util.Date;
13+
import java.util.Locale;
14+
715
import com.vaadin.flow.component.checkbox.Checkbox;
16+
import com.vaadin.flow.component.confirmdialog.ConfirmDialog;
817
import com.vaadin.flow.component.datetimepicker.DateTimePicker;
918
import com.vaadin.flow.component.formlayout.FormLayout;
19+
import com.vaadin.flow.component.formlayout.FormLayout.FormItem;
1020
import com.vaadin.flow.component.html.Span;
1121
import com.vaadin.flow.component.select.Select;
22+
1223
import io.imunity.console.views.directory_browser.EntityWithLabel;
1324
import io.imunity.vaadin.elements.DialogWithActionFooter;
25+
import io.imunity.vaadin.endpoint.common.api.HtmlTooltipFactory;
1426
import pl.edu.icm.unity.base.entity.EntityInformation;
1527
import pl.edu.icm.unity.base.entity.EntityScheduledOperation;
1628
import pl.edu.icm.unity.base.entity.EntityState;
1729
import pl.edu.icm.unity.base.message.MessageSource;
1830

19-
import java.time.Instant;
20-
import java.time.LocalDateTime;
21-
import java.time.ZoneId;
22-
import java.util.Date;
23-
import java.util.Locale;
24-
2531

2632
class ChangeEntityStateDialog extends DialogWithActionFooter
2733
{
2834
private static final Locale EUROPEAN_TIME_FORMAT = Locale.forLanguageTag("DE");
2935

36+
private final HtmlTooltipFactory htmlTooltipFactory;
3037
private final MessageSource msg;
3138
private final EntityWithLabel entity;
3239
private final Callback callback;
@@ -35,12 +42,17 @@ class ChangeEntityStateDialog extends DialogWithActionFooter
3542
private Checkbox scheduleEnable;
3643
private Select<EntityScheduledOperation> entityScheduledChange;
3744
private DateTimePicker changeTime;
38-
private FormLayout.FormItem changeTimeFormItem;
45+
private DateTimePicker removalTime;
46+
private FormItem changeTimeFormItem;
47+
48+
private FormItem removalFormItem;
3949

40-
ChangeEntityStateDialog(MessageSource msg, EntityWithLabel entity, Callback callback)
50+
ChangeEntityStateDialog(MessageSource msg, HtmlTooltipFactory htmlTooltipFactory, EntityWithLabel entity,
51+
Callback callback)
4152
{
4253
super(msg::getMessage);
4354
this.msg = msg;
55+
this.htmlTooltipFactory = htmlTooltipFactory;
4456
this.entity = entity;
4557
this.callback = callback;
4658
setHeaderTitle(msg.getMessage("ChangeEntityStateDialog.caption"));
@@ -58,6 +70,18 @@ private FormLayout getContents()
5870
entityState.setValue(entity.getEntity().getState());
5971
entityState.setWidthFull();
6072

73+
entityState.addValueChangeListener(event ->
74+
{
75+
EntityState newValue = event.getValue();
76+
if (newValue == EntityState.onlyLoginPermitted)
77+
{
78+
removalFormItem.setVisible(true);
79+
} else
80+
{
81+
removalFormItem.setVisible(false);
82+
}
83+
});
84+
6185
scheduleEnable = new Checkbox(msg.getMessage("ChangeEntityStateDialog.enableScheduled"));
6286

6387
EntityInformation initial = entity.getEntity().getEntityInformation();
@@ -67,10 +91,17 @@ private FormLayout getContents()
6791
entityScheduledChange.setItems(EntityScheduledOperation.values());
6892
entityScheduledChange.setItemLabelGenerator(item -> msg.getMessage("EntityScheduledOperation." + item));
6993
entityScheduledChange.setValue(initialOp);
94+
7095

7196
changeTime = new DateTimePicker();
7297
changeTime.setLocale(EUROPEAN_TIME_FORMAT);
7398
changeTime.setRequiredIndicatorVisible(true);
99+
100+
removalTime = new DateTimePicker();
101+
removalTime.setLocale(EUROPEAN_TIME_FORMAT);
102+
removalTime.setRequiredIndicatorVisible(true);
103+
104+
74105
if (initial.getScheduledOperation() != null)
75106
{
76107
scheduleEnable.setValue(true);
@@ -90,25 +121,28 @@ private FormLayout getContents()
90121
});
91122

92123
FormLayout main = new FormLayout();
124+
main.addClassName(MEDIUM_VAADIN_FORM_ITEM_LABEL.getName());
93125
main.setResponsiveSteps(new FormLayout.ResponsiveStep("0", 1));
94-
FormLayout embedded = new FormLayout();
95-
embedded.setResponsiveSteps(new FormLayout.ResponsiveStep("0", 1));
96-
embedded.addFormItem(entityScheduledChange, msg.getMessage("ChangeEntityStateDialog.scheduledOperation"));
97-
changeTimeFormItem = embedded.addFormItem(changeTime,
98-
msg.getMessage("ChangeEntityStateDialog.scheduledChangeTime"));
99-
126+
main.addFormItem(entityState, msg.getMessage("ChangeEntityStateDialog.newState"));
127+
removalFormItem = main.addFormItem(removalTime, msg.getMessage("ChangeEntityStateDialog.removalGracePeriodEnd"));
128+
removalFormItem.add(htmlTooltipFactory.get(msg.getMessage("ChangeEntityStateDialog.removalGracePeriodEndDescription")));
129+
removalFormItem.setVisible(false);
130+
main.addFormItem(scheduleEnable, "");
131+
main.addFormItem(entityScheduledChange, msg.getMessage("ChangeEntityStateDialog.scheduledOperation"));
132+
changeTimeFormItem = main.addFormItem(changeTime,
133+
msg.getMessage("ChangeEntityStateDialog.scheduledChangeTime"));
134+
main.setSizeFull();
135+
136+
100137
if (entity.getEntity().getEntityInformation().getRemovalByUserTime() != null &&
101138
entity.getEntity().getEntityInformation().getState() == EntityState.onlyLoginPermitted)
102139
{
103-
Span infoRemovalByUser = new Span(msg.getMessage("ChangeEntityStateDialog.infoUserScheduledRemoval",
104-
entity.getEntity().getEntityInformation().getRemovalByUserTime()));
105-
main.add(infoRemovalByUser);
140+
removalFormItem.setVisible(true);
141+
removalTime.setValue(LocalDateTime.ofInstant(entity.getEntity().getEntityInformation().getRemovalByUserTime()
142+
.toInstant(), ZoneId.systemDefault()));
106143
}
107144

108-
main.addFormItem(entityState, msg.getMessage("ChangeEntityStateDialog.newState"));
109-
main.addFormItem(scheduleEnable, "");
110-
main.addFormItem(embedded, "");
111-
main.setSizeFull();
145+
112146
return main;
113147
}
114148

@@ -121,6 +155,25 @@ private void onConfirm()
121155
changeTime.setErrorMessage(null);
122156
changeTime.setInvalid(false);
123157

158+
if (newState.equals(EntityState.onlyLoginPermitted))
159+
{
160+
LocalDateTime ldt = removalTime.getValue();
161+
if (ldt == null)
162+
{
163+
removalTime.setErrorMessage(msg.getMessage("fieldRequired"));
164+
removalTime.setInvalid(true);
165+
open();
166+
removalTime.getElement().setAttribute("invalid", true);
167+
return;
168+
}
169+
Date zonedDate = Date.from(ldt.atZone(ZoneId.systemDefault())
170+
.toInstant());
171+
newInfo.setRemovalByUserTime(zonedDate);
172+
} else
173+
{
174+
newInfo.setRemovalByUserTime(null);
175+
}
176+
124177
if (scheduleEnable.getValue())
125178
{
126179
if (changeTime.getValue() == null)
@@ -137,8 +190,23 @@ private void onConfirm()
137190
newInfo.setScheduledOperationTime(zonedDate);
138191
}
139192

140-
if (callback.onChanged(newInfo))
141-
close();
193+
if (newInfo.getScheduledOperation() != null && newInfo.getRemovalByUserTime() != null)
194+
{
195+
ConfirmDialog confirm = new ConfirmDialog();
196+
confirm.setConfirmButton(msg.getMessage("ok"), e ->
197+
{
198+
if (callback.onChanged(newInfo))
199+
close();
200+
});
201+
confirm.setCancelable(true);
202+
confirm.add(new Span(msg.getMessage("ChangeEntityStateDialog.warningScheduledChangeAndRemoval")));
203+
confirm.open();
204+
205+
} else
206+
{
207+
if (callback.onChanged(newInfo))
208+
close();
209+
}
142210
}
143211

144212
interface Callback

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

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
import io.imunity.console.views.directory_browser.EntityWithLabel;
1414
import io.imunity.vaadin.elements.NotificationPresenter;
1515
import io.imunity.vaadin.elements.grid.SingleActionHandler;
16+
import io.imunity.vaadin.endpoint.common.api.HtmlTooltipFactory;
1617
import pl.edu.icm.unity.base.entity.EntityInformation;
1718
import pl.edu.icm.unity.base.entity.EntityParam;
19+
import pl.edu.icm.unity.base.entity.EntityState;
1820
import pl.edu.icm.unity.base.message.MessageSource;
1921
import pl.edu.icm.unity.engine.api.EntityManagement;
2022

@@ -24,13 +26,15 @@ class ChangeEntityStateHandler
2426
private final EntityManagement identitiesMan;
2527
private final MessageSource msg;
2628
private final NotificationPresenter notificationPresenter;
27-
29+
private final HtmlTooltipFactory htmlTooltipFactory;
30+
2831
ChangeEntityStateHandler(EntityManagement identitiesMan, MessageSource msg,
29-
NotificationPresenter notificationPresenter)
32+
NotificationPresenter notificationPresenter, HtmlTooltipFactory htmlTooltipFactory)
3033
{
3134
this.identitiesMan = identitiesMan;
3235
this.msg = msg;
3336
this.notificationPresenter = notificationPresenter;
37+
this.htmlTooltipFactory = htmlTooltipFactory;
3438
}
3539

3640
SingleActionHandler<IdentityEntry> getAction(Runnable refreshCallback)
@@ -46,7 +50,7 @@ SingleActionHandler<IdentityEntry> getAction(Runnable refreshCallback)
4650
private void showDialog(Set<IdentityEntry> selection, Runnable refreshCallback)
4751
{
4852
EntityWithLabel entity = selection.iterator().next().getSourceEntity();
49-
new ChangeEntityStateDialog(msg, entity, newState ->
53+
new ChangeEntityStateDialog(msg, htmlTooltipFactory, entity, newState ->
5054
setEntityStatus(entity.getEntity().getId(), newState, refreshCallback)
5155
).open();
5256
}
@@ -57,7 +61,13 @@ private boolean setEntityStatus(long entityId, EntityInformation newState,
5761
try
5862
{
5963
EntityParam entity = new EntityParam(entityId);
60-
identitiesMan.setEntityStatus(entity, newState.getState());
64+
if (newState.getState().equals(EntityState.onlyLoginPermitted))
65+
{
66+
identitiesMan.scheduleRemovalByUser(entity, newState.getRemovalByUserTime());
67+
}else {
68+
identitiesMan.setEntityStatus(entity, newState.getState());
69+
}
70+
6171
identitiesMan.scheduleEntityChange(entity, newState.getScheduledOperationTime(),
6272
newState.getScheduledOperation());
6373
refreshCallback.run();

console/src/main/resources/messages/console/messages.properties

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1104,6 +1104,9 @@ ChangeEntityStateDialog.newState=New status:
11041104
ChangeEntityStateDialog.enableScheduled=Schedule entity change in future
11051105
ChangeEntityStateDialog.scheduledOperation=Scheduled operation:
11061106
ChangeEntityStateDialog.scheduledChangeTime=Operation time:
1107+
ChangeEntityStateDialog.removalGracePeriodEnd=Removal grace period end:
1108+
ChangeEntityStateDialog.removalGracePeriodEndDescription=This time is usually set by the user, when deleting own account. Entity will be removed after this time, unless user sings-in before. In such case the status of the entity will be reset to VALID.
1109+
ChangeEntityStateDialog.warningScheduledChangeAndRemoval=Both user controlled account removal and admin-scheduled status change are set. Only the action with earlier time will be executed, unless user signs-in before this time.
11071110

11081111
EntityCreation.caption=New entity creation
11091112
EntityCreation.addToGroup=After creation add to group {0}
@@ -1323,7 +1326,7 @@ EntityScheduledOperation.DISABLE=Disable
13231326
EntityState.valid=ENABLED
13241327
EntityState.authenticationDisabled=LOGIN DISABLED
13251328
EntityState.disabled=DISABLED
1326-
EntityState.onlyLoginPermitted=DISABLED, ONLY LOGIN PERMITTED
1329+
EntityState.onlyLoginPermitted=DISABLED, TO BE RMOVED
13271330

13281331
IdentityDetails.entityDetailsCaption=Entity details
13291332
IdentityDetails.id=Displayed name:

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,10 @@ 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.");
635639
long entityId = idResolver.getEntityId(toChange);
636640
authz.checkAuthorization(authz.isSelf(entityId), AuthzCapability.identityModify);
637641
EntityInformation current = entityDAO.getByKey(entityId);

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

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -421,18 +421,6 @@ 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-
}
435-
436424
@Test
437425
public void shouldFailToAddToSubgoupWhenNotInParent() throws Exception
438426
{

0 commit comments

Comments
 (0)