Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SYNCOPE-1772] Adding MfaTrustedDevice to AuhtProfile #502

Merged
merged 3 commits into from
Aug 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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() {

Check notice

Code scanning / CodeQL

Exposing internal representation

getMfaTrustedDevices exposes the internal representation stored in field mfaTrustedDevices. The value may be modified [after this call to getMfaTrustedDevices](1).
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