Skip to content

Commit

Permalink
[SYNCOPE-1772] Adding MfaTrustedDevice to AuhtProfile (#502) (#503)
Browse files Browse the repository at this point in the history
  • Loading branch information
ilgrosso authored Aug 5, 2023
1 parent c6d3dba commit 7d75c9f
Show file tree
Hide file tree
Showing 34 changed files with 1,068 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import org.apache.syncope.common.lib.wa.GoogleMfaAuthAccount;
import org.apache.syncope.common.lib.wa.GoogleMfaAuthToken;
import org.apache.syncope.common.lib.wa.ImpersonationAccount;
import org.apache.syncope.common.lib.wa.MfaTrustedDevice;
import org.apache.syncope.common.lib.wa.U2FDevice;
import org.apache.syncope.common.lib.wa.WebAuthnDeviceCredential;
import org.apache.wicket.PageReference;
Expand Down Expand Up @@ -157,6 +158,15 @@ protected boolean isCondition(final IModel<AuthProfileTO> rowModel) {
return !rowModel.getObject().getU2FRegisteredDevices().isEmpty();
}
});
columns.add(new BooleanConditionColumn<>(new StringResourceModel("mfaTrustedDevices")) {

private static final long serialVersionUID = -8236820422411536323L;

@Override
protected boolean isCondition(final IModel<AuthProfileTO> rowModel) {
return !rowModel.getObject().getMfaTrustedDevices().isEmpty();
}
});
columns.add(new BooleanConditionColumn<>(new StringResourceModel("webAuthnAccount")) {

private static final long serialVersionUID = -8236820422411536323L;
Expand Down Expand Up @@ -368,6 +378,57 @@ protected List<IColumn<U2FDevice, String>> getColumns() {
}
}, ActionLink.ActionType.FO_EDIT, AMEntitlement.AUTH_PROFILE_UPDATE);

panel.add(new ActionLink<>() {

private static final long serialVersionUID = -3722207913631435501L;

@Override
public void onClick(final AjaxRequestTarget target, final AuthProfileTO ignore) {
model.setObject(restClient.read(model.getObject().getKey()));
target.add(authProfileModal.setContent(new ModalDirectoryPanel<>(
authProfileModal,
new AuthProfileItemDirectoryPanel<MfaTrustedDevice>(
"panel", restClient, authProfileModal, model.getObject(), pageRef) {

private static final long serialVersionUID = 5788448799796630011L;

@Override
protected List<MfaTrustedDevice> getItems() {
return model.getObject().getMfaTrustedDevices();
}

@Override
protected MfaTrustedDevice defaultItem() {
return new MfaTrustedDevice();
}

@Override
protected String sortProperty() {
return "id";
}

@Override
protected String paginatorRowsKey() {
return AMConstants.PREF_AUTHPROFILE_MFA_TRUSTED_FDEVICES_PAGINATOR_ROWS;
}

@Override
protected List<IColumn<MfaTrustedDevice, String>> getColumns() {
List<IColumn<MfaTrustedDevice, String>> columns = new ArrayList<>();
columns.add(new PropertyColumn<>(new ResourceModel("id"), "id", "id"));
columns.add(new PropertyColumn<>(new ResourceModel("name"), "name", "name"));
columns.add(new DatePropertyColumn<>(
new ResourceModel("recordDate"), "recordDate", "recordDate"));
columns.add(new DatePropertyColumn<>(
new ResourceModel("expirationDate"), "expirationDate", "expirationDate"));
return columns;
}
}, pageRef)));
authProfileModal.header(new Model<>(getString("mfaTrustedDevices", model)));
authProfileModal.show(true);
}
}, ActionLink.ActionType.DOWN, AMEntitlement.AUTH_PROFILE_UPDATE);

panel.add(new ActionLink<>() {

private static final long serialVersionUID = -3722207913631435501L;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,11 @@ public final class AMConstants {
public static final String PREF_AUTHPROFILE_GOOGLEMFAAUTHACCOUNTS_PAGINATOR_ROWS =
"authprofile.googlemfaauthaccounts.paginator.rows";

public static final String PREF_AUTHPROFILE_U2FDEVICES_PAGINATOR_ROWS = "authprofile.u2fdevices.paginator.rows";
public static final String PREF_AUTHPROFILE_U2FDEVICES_PAGINATOR_ROWS =
"authprofile.u2fdevices.paginator.rows";

public static final String PREF_AUTHPROFILE_MFA_TRUSTED_FDEVICES_PAGINATOR_ROWS =
"authprofile.mfaTrustedDevices.paginator.rows";

public static final String PREF_AUTHPROFILE_WEBAUTHNDEVICECREDENTIALS_PAGINATOR_ROWS =
"authprofile.webAuthnDeviceCredentials.paginator.rows";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,8 @@ json=JSON
html.class=fas fa-at
html.title=webauthn
webAuthnDeviceCredentials=WebAuthn Device Credentials
expirationDate=Expiration Date
recordDate=Record Date
mfaTrustedDevices=MFA Devices
down.title=mfa devices
down.class=fas fa-barcode
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,8 @@ json=JSON
html.class=fas fa-at
html.title=webauthn
webAuthnDeviceCredentials=WebAuthn Device Credentials
expirationDate=Expiration Date
recordDate=Record Date
mfaTrustedDevices=MFA Devices
down.title=mfa devices
down.class=fas fa-barcode
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,8 @@ json=JSON
html.class=fas fa-at
html.title=webauthn
webAuthnDeviceCredentials=Dispositivi Credenziali WebAuthn
expirationDate=Scadenza
recordDate=Memorizzazione
mfaTrustedDevices=Dispositivi MFA
down.title=dispositivi mfa
down.class=fas fa-barcode
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,8 @@ json=JSON
html.class=fas fa-at
html.title=webauthn
webAuthnDeviceCredentials=WebAuthn Device Credentials
expirationDate=Expiration Date
recordDate=Record Date
mfaTrustedDevices=MFA Devices
down.title=mfa devices
down.class=fas fa-barcode
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,8 @@ json=JSON
html.class=fas fa-at
html.title=webauthn
webAuthnDeviceCredentials=WebAuthn Device Credentials
expirationDate=Expiration Date
recordDate=Record Date
mfaTrustedDevices=MFA Devices
down.title=mfa devices
down.class=fas fa-barcode
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,8 @@ json=JSON
html.class=fas fa-at
html.title=webauthn
webAuthnDeviceCredentials=WebAuthn Device Credentials
expirationDate=Expiration Date
recordDate=Record Date
mfaTrustedDevices=MFA Devices
down.title=mfa devices
down.class=fas fa-barcode
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@

import java.io.Serializable;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.Optional;
import org.apache.commons.lang3.StringUtils;
Expand All @@ -46,39 +48,71 @@ public String format(final Date date) {
public String format(final OffsetDateTime date) {
return Optional.ofNullable(date).map(v -> fdf.format(convert(date))).orElse(StringUtils.EMPTY);
}

public String format(final ZonedDateTime date) {
return Optional.ofNullable(date).map(v -> fdf.format(convert(date))).orElse(StringUtils.EMPTY);
}
}

public static class WrappedDateModel implements IModel<Date>, Serializable {
public static final class WrappedDateModel implements IModel<Date>, Serializable {

private static final long serialVersionUID = 31027882183172L;

private final IModel<OffsetDateTime> wrapped;
public static WrappedDateModel ofOffset(final IModel<OffsetDateTime> offset) {
WrappedDateModel instance = new WrappedDateModel();
instance.offset = offset;
return instance;
}

public static WrappedDateModel ofZoned(final IModel<ZonedDateTime> zoned) {
WrappedDateModel instance = new WrappedDateModel();
instance.zoned = zoned;
return instance;
}

private IModel<OffsetDateTime> offset;

public WrappedDateModel(final IModel<OffsetDateTime> wrapped) {
this.wrapped = wrapped;
private IModel<ZonedDateTime> zoned;

private WrappedDateModel() {
// private constructor for static utility class
}

@Override
public Date getObject() {
return convert(wrapped.getObject());
return offset == null ? convert(zoned.getObject()) : convert(offset.getObject());
}

@Override
public void setObject(final Date object) {
wrapped.setObject(convert(object));
if (offset == null) {
zoned.setObject(toZonedDateTime(object));
} else {
offset.setObject(toOffsetDateTime(object));
}
}
}

public static final ZoneOffset DEFAULT_OFFSET = OffsetDateTime.now().getOffset();

public static final ZoneId DEFAULT_ZONE = ZonedDateTime.now().getZone();

public static Date convert(final OffsetDateTime date) {
return Optional.ofNullable(date).map(v -> new Date(v.toInstant().toEpochMilli())).orElse(null);
}

public static OffsetDateTime convert(final Date date) {
public static Date convert(final ZonedDateTime date) {
return Optional.ofNullable(date).map(v -> new Date(v.toInstant().toEpochMilli())).orElse(null);
}

public static OffsetDateTime toOffsetDateTime(final Date date) {
return Optional.ofNullable(date).map(v -> v.toInstant().atOffset(DEFAULT_OFFSET)).orElse(null);
}

public static ZonedDateTime toZonedDateTime(final Date date) {
return Optional.ofNullable(date).map(v -> ZonedDateTime.ofInstant(v.toInstant(), DEFAULT_ZONE)).orElse(null);
}

private DateOps() {
// private constructor for static utility class
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.lang.reflect.ParameterizedType;
import java.time.Duration;
import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
Expand Down Expand Up @@ -301,7 +302,10 @@ private Triple<FieldPanel, Boolean, Optional<String>> buildSinglePanel(
panel = new AjaxDateTimeFieldPanel(id, fieldName, model,
DateFormatUtils.ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT);
} else if (OffsetDateTime.class.equals(type)) {
panel = new AjaxDateTimeFieldPanel(id, fieldName, new DateOps.WrappedDateModel(model),
panel = new AjaxDateTimeFieldPanel(id, fieldName, DateOps.WrappedDateModel.ofOffset(model),
DateFormatUtils.ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT);
} else if (ZonedDateTime.class.equals(type)) {
panel = new AjaxDateTimeFieldPanel(id, fieldName, DateOps.WrappedDateModel.ofZoned(model),
DateFormatUtils.ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT);
} else if (type.isEnum()) {
panel = new AjaxDropDownChoicePanel(id, fieldName, model).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public void delete(final String reportKey) {
@Override
public void startExecution(final String reportKey, final Date startAt) {
getService(ReportService.class).execute(new ExecSpecs.Builder().key(reportKey).
startAt(DateOps.convert(startAt)).build());
startAt(DateOps.toOffsetDateTime(startAt)).build());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ public void startExecution(final String taskKey, final Date startAt) {

public void startExecution(final String taskKey, final Date startAt, final boolean dryRun) {
getService(TaskService.class).execute(new ExecSpecs.Builder().key(taskKey).
startAt(DateOps.convert(startAt)).dryRun(dryRun).build());
startAt(DateOps.toOffsetDateTime(startAt)).dryRun(dryRun).build());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table;

import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
import java.util.Date;
import org.apache.syncope.client.console.SyncopeConsoleSession;
import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
Expand Down Expand Up @@ -49,6 +50,8 @@ public void populateItem(final Item<ICellPopulator<T>> item, final String compon
String convertedDate = "";
if (date.getObject() instanceof OffsetDateTime) {
convertedDate = SyncopeConsoleSession.get().getDateFormat().format((OffsetDateTime) date.getObject());
} else if (date.getObject() instanceof ZonedDateTime) {
convertedDate = SyncopeConsoleSession.get().getDateFormat().format((ZonedDateTime) date.getObject());
} else if (date.getObject() instanceof Date) {
convertedDate = SyncopeConsoleSession.get().getDateFormat().format((Date) date.getObject());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,14 +151,14 @@ private static class StartEnd extends WizardStep {
add(new AjaxDateTimeFieldPanel(
"start",
"start",
new DateOps.WrappedDateModel(new PropertyModel<>(modelObject, "start")),
DateOps.WrappedDateModel.ofOffset(new PropertyModel<>(modelObject, "start")),
DateFormatUtils.ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT).
addRequiredLabel());

add(new AjaxDateTimeFieldPanel(
"end",
"end",
new DateOps.WrappedDateModel(new PropertyModel<>(modelObject, "end")),
DateOps.WrappedDateModel.ofOffset(new PropertyModel<>(modelObject, "end")),
DateFormatUtils.ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.apache.syncope.common.lib.wa.GoogleMfaAuthAccount;
import org.apache.syncope.common.lib.wa.GoogleMfaAuthToken;
import org.apache.syncope.common.lib.wa.ImpersonationAccount;
import org.apache.syncope.common.lib.wa.MfaTrustedDevice;
import org.apache.syncope.common.lib.wa.U2FDevice;
import org.apache.syncope.common.lib.wa.WebAuthnDeviceCredential;

Expand Down Expand Up @@ -95,6 +96,21 @@ public AuthProfileTO.Builder u2fRegisteredDevices(final Collection<U2FDevice> de
return this;
}

public AuthProfileTO.Builder mfaTrustedDevice(final MfaTrustedDevice device) {
instance.getMfaTrustedDevices().add(device);
return this;
}

public AuthProfileTO.Builder mfaTrustedDevices(final MfaTrustedDevice... devices) {
instance.getMfaTrustedDevices().addAll(List.of(devices));
return this;
}

public AuthProfileTO.Builder mfaTrustedDevices(final Collection<MfaTrustedDevice> devices) {
instance.getMfaTrustedDevices().addAll(devices);
return this;
}

public AuthProfileTO.Builder credential(final WebAuthnDeviceCredential credential) {
instance.getWebAuthnDeviceCredentials().add(credential);
return this;
Expand Down Expand Up @@ -127,6 +143,8 @@ public AuthProfileTO build() {

private final List<U2FDevice> u2fRegisteredDevices = new ArrayList<>();

private final List<MfaTrustedDevice> mfaTrustedDevices = new ArrayList<>();

private final List<WebAuthnDeviceCredential> webAuthnDeviceCredentials = new ArrayList<>();

@Override
Expand Down Expand Up @@ -172,6 +190,12 @@ public List<U2FDevice> getU2FRegisteredDevices() {
return u2fRegisteredDevices;
}

@JacksonXmlElementWrapper(localName = "mfaTrustedDevices")
@JacksonXmlProperty(localName = "mfaTrustedDevice")
public List<MfaTrustedDevice> getMfaTrustedDevices() {
return mfaTrustedDevices;
}

@JacksonXmlElementWrapper(localName = "credentials")
@JacksonXmlProperty(localName = "credential")
public List<WebAuthnDeviceCredential> getWebAuthnDeviceCredentials() {
Expand All @@ -187,6 +211,7 @@ public int hashCode() {
append(googleMfaAuthTokens).
append(googleMfaAuthAccounts).
append(u2fRegisteredDevices).
append(mfaTrustedDevices).
append(webAuthnDeviceCredentials).
build();
}
Expand All @@ -210,6 +235,7 @@ public boolean equals(final Object obj) {
append(googleMfaAuthTokens, other.googleMfaAuthTokens).
append(googleMfaAuthAccounts, other.googleMfaAuthAccounts).
append(u2fRegisteredDevices, other.u2fRegisteredDevices).
append(mfaTrustedDevices, other.mfaTrustedDevices).
append(webAuthnDeviceCredentials, other.webAuthnDeviceCredentials).
build();
}
Expand Down
Loading

0 comments on commit 7d75c9f

Please sign in to comment.