SEBSERV-469 implementation
This commit is contained in:
parent
074b63580b
commit
29265dd7e1
16 changed files with 200 additions and 87 deletions
|
@ -11,6 +11,11 @@ package ch.ethz.seb.sebserver.gbl.model.sebconfig;
|
|||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hibernate.validator.constraints.URL;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DateTimeZone;
|
||||
|
@ -52,6 +57,7 @@ public final class SEBClientConfig implements GrantEntity, Activatable {
|
|||
public static final String ATTR_ENCRYPT_CERTIFICATE_ASYM = "cert_encryption_asym";
|
||||
|
||||
public static final String FILTER_ATTR_CREATION_DATE = "creation_date";
|
||||
public static final String ATTR_EXAM_SELECTION = "exam_selection";
|
||||
|
||||
public enum ConfigPurpose {
|
||||
START_EXAM,
|
||||
|
@ -174,6 +180,8 @@ public final class SEBClientConfig implements GrantEntity, Activatable {
|
|||
|
||||
@JsonProperty(SEB_CLIENT_CONFIGURATION.ATTR_LAST_UPDATE_USER)
|
||||
public final String lastUpdateUser;
|
||||
@JsonProperty(SEBClientConfig.ATTR_EXAM_SELECTION)
|
||||
public final Set<Long> selectedExams;
|
||||
|
||||
@JsonCreator
|
||||
public SEBClientConfig(
|
||||
|
@ -204,7 +212,8 @@ public final class SEBClientConfig implements GrantEntity, Activatable {
|
|||
@JsonProperty(ATTR_ENCRYPT_CERTIFICATE_ASYM) final Boolean encryptCertificateAsym,
|
||||
@JsonProperty(SEB_CLIENT_CONFIGURATION.ATTR_ACTIVE) final Boolean active,
|
||||
@JsonProperty(SEB_CLIENT_CONFIGURATION.ATTR_LAST_UPDATE_TIME) final DateTime lastUpdateTime,
|
||||
@JsonProperty(SEB_CLIENT_CONFIGURATION.ATTR_LAST_UPDATE_USER) final String lastUpdateUser) {
|
||||
@JsonProperty(SEB_CLIENT_CONFIGURATION.ATTR_LAST_UPDATE_USER) final String lastUpdateUser,
|
||||
@JsonProperty(SEBClientConfig.ATTR_EXAM_SELECTION) final Set<Long> selectedExams) {
|
||||
|
||||
this.id = id;
|
||||
this.institutionId = institutionId;
|
||||
|
@ -240,6 +249,7 @@ public final class SEBClientConfig implements GrantEntity, Activatable {
|
|||
this.active = active;
|
||||
this.lastUpdateTime = lastUpdateTime;
|
||||
this.lastUpdateUser = lastUpdateUser;
|
||||
this.selectedExams = Utils.immutableSetOf(selectedExams);
|
||||
}
|
||||
|
||||
public SEBClientConfig(final Long institutionId, final POSTMapper postParams) {
|
||||
|
@ -281,6 +291,7 @@ public final class SEBClientConfig implements GrantEntity, Activatable {
|
|||
this.active = false;
|
||||
this.lastUpdateTime = postParams.getDateTime(CONFIGURATION_NODE.ATTR_LAST_UPDATE_TIME);
|
||||
this.lastUpdateUser = postParams.getString(CONFIGURATION_NODE.ATTR_LAST_UPDATE_USER);
|
||||
this.selectedExams = Utils.immutableSetOf(Utils.getIdsFromString(postParams.getString(SEBClientConfig.ATTR_EXAM_SELECTION)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -424,6 +435,10 @@ public final class SEBClientConfig implements GrantEntity, Activatable {
|
|||
return this.lastUpdateUser;
|
||||
}
|
||||
|
||||
public Set<Long> getSelectedExams() {
|
||||
return selectedExams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
|
@ -503,7 +518,8 @@ public final class SEBClientConfig implements GrantEntity, Activatable {
|
|||
this.encryptCertificateAsym,
|
||||
this.active,
|
||||
this.lastUpdateTime,
|
||||
this.lastUpdateUser);
|
||||
this.lastUpdateUser,
|
||||
this.selectedExams);
|
||||
}
|
||||
|
||||
public static SEBClientConfig createNew(final Long institutionId, final long pingIterval) {
|
||||
|
@ -533,6 +549,7 @@ public final class SEBClientConfig implements GrantEntity, Activatable {
|
|||
false,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
null);
|
||||
}
|
||||
|
||||
|
|
|
@ -935,4 +935,22 @@ public final class Utils {
|
|||
return "Basic " + base64Creds;
|
||||
}
|
||||
|
||||
public static Set<Long> getIdsFromString(final String idsString) {
|
||||
if (StringUtils.isBlank(idsString)) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
return Arrays
|
||||
.stream(StringUtils.split(idsString, Constants.LIST_SEPARATOR_CHAR))
|
||||
.map(s -> {
|
||||
try {
|
||||
return Long.valueOf(s);
|
||||
} catch (final Exception e) {
|
||||
log.warn("Failed to parse String: {} to Long", s);
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -134,6 +134,9 @@ public class SEBClientConfigForm implements TemplateComposer {
|
|||
private static final LocTextKey FORM_CONFIRM_ENCRYPT_SECRET_TEXT_KEY =
|
||||
new LocTextKey("sebserver.clientconfig.form.encryptSecret.confirm");
|
||||
|
||||
private static final LocTextKey FORM_EXAM_SELECTION_TEXT_KEY =
|
||||
new LocTextKey("sebserver.clientconfig.form.examselection");
|
||||
|
||||
private static final LocTextKey DELETE_CONFIRM =
|
||||
new LocTextKey("sebserver.clientconfig.action.delete.confirm");
|
||||
private static final LocTextKey DELETE_SUCCESS =
|
||||
|
@ -409,20 +412,28 @@ public class SEBClientConfigForm implements TemplateComposer {
|
|||
.mandatory(!isReadonly))
|
||||
.withDefaultSpanEmptyCell(3)
|
||||
|
||||
.addField(FormBuilder.multiComboSelection(
|
||||
SEBClientConfig.ATTR_EXAM_SELECTION,
|
||||
FORM_EXAM_SELECTION_TEXT_KEY,
|
||||
StringUtils.join(clientConfig.selectedExams, Constants.LIST_SEPARATOR),
|
||||
() -> pageService.getResourceService().getExamLogSelectionResources())
|
||||
.withInputSpan(5))
|
||||
.withDefaultSpanEmptyCell(1);
|
||||
|
||||
// VDI
|
||||
|
||||
.withDefaultSpanInput(2)
|
||||
.addFieldIf(
|
||||
() -> false, // TODO skipped for version 1.2 --> 1.3 or 1.4
|
||||
() -> FormBuilder.singleSelection(
|
||||
SEBClientConfig.ATTR_VDI_TYPE,
|
||||
VDI_TYPE_TEXT_KEY,
|
||||
clientConfig.vdiType != null
|
||||
? clientConfig.vdiType.name()
|
||||
: SEBClientConfig.VDIType.NO.name(),
|
||||
() -> this.pageService.getResourceService().vdiTypeResources())
|
||||
.mandatory(!isReadonly))
|
||||
.withDefaultSpanEmptyCell(3);
|
||||
// .withDefaultSpanInput(2)
|
||||
// .addFieldIf(
|
||||
// () -> false, // TODO skipped for version 1.2 --> 1.3 or 1.4
|
||||
// () -> FormBuilder.singleSelection(
|
||||
// SEBClientConfig.ATTR_VDI_TYPE,
|
||||
// VDI_TYPE_TEXT_KEY,
|
||||
// clientConfig.vdiType != null
|
||||
// ? clientConfig.vdiType.name()
|
||||
// : SEBClientConfig.VDIType.NO.name(),
|
||||
// () -> this.pageService.getResourceService().vdiTypeResources())
|
||||
// .mandatory(!isReadonly))
|
||||
// .withDefaultSpanEmptyCell(3);
|
||||
|
||||
// VDI Attributes
|
||||
|
||||
|
@ -460,7 +471,10 @@ public class SEBClientConfigForm implements TemplateComposer {
|
|||
FALLBACK_TEXT_KEY,
|
||||
clientConfig.fallback != null
|
||||
? clientConfig.fallback.toString()
|
||||
: Constants.FALSE_STRING));
|
||||
: Constants.FALSE_STRING))
|
||||
.withDefaultSpanEmptyCell(3)
|
||||
|
||||
;
|
||||
|
||||
// Fallback Attributes
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ package ch.ethz.seb.sebserver.gui.form;
|
|||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
@ -122,6 +123,7 @@ public final class SelectionFieldBuilder extends FieldBuilder<String> {
|
|||
this.itemsSupplier.get()
|
||||
.stream()
|
||||
.filter(tuple -> keys.contains(tuple._1))
|
||||
.sorted((t1, t2) -> String.CASE_INSENSITIVE_ORDER.compare(t1._2, t2._2))
|
||||
.map(tuple -> tuple._1)
|
||||
.forEach(v -> buildReadonlyLabel(builder, composite, v, 1));
|
||||
}
|
||||
|
|
|
@ -8,22 +8,17 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.gui.widget;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.eclipse.rap.rwt.widgets.DropDown;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.graphics.Point;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.swt.widgets.Event;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
import org.eclipse.swt.widgets.Listener;
|
||||
import org.eclipse.swt.widgets.Text;
|
||||
import org.eclipse.swt.widgets.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -33,13 +28,11 @@ import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
|||
|
||||
public final class MultiSelectionCombo extends Composite implements Selection {
|
||||
|
||||
public static final LocTextKey DESELECT_TOOLTIP = new LocTextKey( "sebserver.form.multiselect.deselect.tooltip" );
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(MultiSelectionCombo.class);
|
||||
private static final long serialVersionUID = -7787134114963647332L;
|
||||
|
||||
private final WidgetFactory widgetFactory;
|
||||
|
||||
private final List<Control> selectionControls = new ArrayList<>();
|
||||
|
||||
private final List<Tuple<String>> valueMapping = new ArrayList<>();
|
||||
private final List<Tuple<String>> availableValues = new ArrayList<>();
|
||||
private final List<Tuple<String>> selectedValues = new ArrayList<>();
|
||||
|
@ -50,7 +43,10 @@ public final class MultiSelectionCombo extends Composite implements Selection {
|
|||
private final Composite updateAnchor;
|
||||
private final String testKey;
|
||||
|
||||
private final Table selectionTable;
|
||||
|
||||
private Listener listener = null;
|
||||
private WidgetFactory widgetFactory;
|
||||
|
||||
MultiSelectionCombo(
|
||||
final Composite parent,
|
||||
|
@ -78,7 +74,7 @@ public final class MultiSelectionCombo extends Composite implements Selection {
|
|||
this.textInput.addListener(SWT.FocusIn, event -> openDropDown());
|
||||
this.textInput.addListener(SWT.Modify, event -> openDropDown());
|
||||
this.textInput.addListener(SWT.MouseUp, event -> openDropDown());
|
||||
this.dropDown.addListener(SWT.Selection, event -> {
|
||||
this.dropDown.addListener(SWT.DefaultSelection, event -> {
|
||||
final int selectionIndex = this.dropDown.getSelectionIndex();
|
||||
if (selectionIndex >= 0) {
|
||||
final String selectedItem = this.dropDown.getItems()[selectionIndex];
|
||||
|
@ -86,21 +82,29 @@ public final class MultiSelectionCombo extends Composite implements Selection {
|
|||
}
|
||||
});
|
||||
|
||||
selectionTable = widgetFactory.tableLocalized(this, SWT.NONE);
|
||||
final GridLayout tableLayout = new GridLayout(1, true);
|
||||
selectionTable.setLayout(tableLayout);
|
||||
final GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
|
||||
selectionTable.setLayoutData(gridData);
|
||||
//selectionTable.setToolTipText();
|
||||
selectionTable.addListener(SWT.MouseDoubleClick, this::removeComboSelection);
|
||||
selectionTable.addListener(SWT.Selection, event -> {
|
||||
selectionTable.setSelection(-1);
|
||||
});
|
||||
selectionTable.setHeaderVisible(false);
|
||||
selectionTable.setLinesVisible(true);
|
||||
|
||||
this.updateAnchor = updateAnchor;
|
||||
}
|
||||
|
||||
private void openDropDown() {
|
||||
final String text = this.textInput.getText();
|
||||
if (text == null) {
|
||||
this.dropDown.setVisible(false);
|
||||
@Override
|
||||
public void setToolTipText(final String tooltipText) {
|
||||
if (tooltipText == null) {
|
||||
super.setToolTipText(widgetFactory.getI18nSupport().getText(DESELECT_TOOLTIP));
|
||||
return;
|
||||
}
|
||||
this.dropDown.setItems(this.availableValues
|
||||
.stream()
|
||||
.filter(it -> it._2 != null && it._2.startsWith(text))
|
||||
.map(t -> t._2).toArray(String[]::new));
|
||||
this.dropDown.setSelectionIndex(0);
|
||||
this.dropDown.setVisible(true);
|
||||
super.setToolTipText(tooltipText + "\n\n" + widgetFactory.getI18nSupport().getText(DESELECT_TOOLTIP));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -157,9 +161,6 @@ public final class MultiSelectionCombo extends Composite implements Selection {
|
|||
@Override
|
||||
public void clear() {
|
||||
this.selectedValues.clear();
|
||||
this.selectionControls
|
||||
.forEach(Control::dispose);
|
||||
this.selectionControls.clear();
|
||||
this.availableValues.clear();
|
||||
this.availableValues.addAll(this.valueMapping);
|
||||
}
|
||||
|
@ -170,42 +171,39 @@ public final class MultiSelectionCombo extends Composite implements Selection {
|
|||
}
|
||||
|
||||
this.selectedValues.add(item);
|
||||
final Label label = this.widgetFactory.label(this, item._2);
|
||||
label.setData(OPTION_VALUE, item._2);
|
||||
final GridData textCell = new GridData(SWT.LEFT, SWT.CENTER, true, true);
|
||||
label.setLayoutData(textCell);
|
||||
label.addListener(SWT.MouseDoubleClick, this::removeComboSelection);
|
||||
this.selectionControls.add(label);
|
||||
|
||||
WidgetFactory.setARIALabel(label, item._2);
|
||||
WidgetFactory.setTestId(label, (this.testKey != null) ? this.testKey + "_" + item._1 : item._1);
|
||||
sortSelectedTable();
|
||||
|
||||
this.availableValues.remove(item);
|
||||
PageService.updateScrolledComposite(this);
|
||||
this.updateAnchor.layout(true, true);
|
||||
}
|
||||
|
||||
private void sortSelectedTable() {
|
||||
selectionTable.removeAll();
|
||||
selectedValues.sort((t1, t2) -> String.CASE_INSENSITIVE_ORDER.compare(t1._2, t2._2));
|
||||
selectedValues.stream().forEach(t -> {
|
||||
final TableItem tItem = new TableItem(selectionTable, SWT.NONE);
|
||||
tItem.setText(0, t._2);
|
||||
tItem.setData("tuple", t);
|
||||
WidgetFactory.setARIALabel(tItem, t._2);
|
||||
WidgetFactory.setTestId(tItem, (this.testKey != null) ? this.testKey + "_" + t._1 : t._1);
|
||||
});
|
||||
}
|
||||
|
||||
private void removeComboSelection(final Event event) {
|
||||
if (event.widget == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String selectionKey = (String) event.widget.getData(OPTION_VALUE);
|
||||
final Optional<Control> findFirst = this.selectionControls.stream()
|
||||
.filter(t -> selectionKey.equals(t.getData(OPTION_VALUE)))
|
||||
.findFirst();
|
||||
if (!findFirst.isPresent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Control control = findFirst.get();
|
||||
final int indexOf = this.selectionControls.indexOf(control);
|
||||
this.selectionControls.remove(control);
|
||||
control.dispose();
|
||||
|
||||
final Tuple<String> value = this.selectedValues.remove(indexOf);
|
||||
final TableItem item = selectionTable.getItem(new Point(event.x, event.y));
|
||||
@SuppressWarnings("unchecked")
|
||||
final Tuple<String> value = (Tuple<String>) item.getData("tuple");
|
||||
this.selectedValues.remove(value);
|
||||
this.availableValues.add(value);
|
||||
|
||||
sortSelectedTable();
|
||||
|
||||
PageService.updateScrolledComposite(this);
|
||||
this.updateAnchor.layout(true, true);
|
||||
if (this.listener != null) {
|
||||
|
@ -238,4 +236,18 @@ public final class MultiSelectionCombo extends Composite implements Selection {
|
|||
return findFirst.orElse(null);
|
||||
}
|
||||
|
||||
private void openDropDown() {
|
||||
final String text = this.textInput.getText();
|
||||
if (text == null) {
|
||||
this.dropDown.setVisible(false);
|
||||
return;
|
||||
}
|
||||
this.dropDown.setItems(this.availableValues
|
||||
.stream()
|
||||
.filter(it -> it._2 != null && it._2.startsWith(text))
|
||||
.map(t -> t._2).toArray(String[]::new));
|
||||
this.dropDown.setSelectionIndex(0);
|
||||
this.dropDown.setVisible(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -489,7 +489,11 @@ public class SEBClientConfigDAOImpl implements SEBClientConfigDAO {
|
|||
additionalAttributes.containsKey(SEBClientConfig.ATTR_ENCRYPT_CERTIFICATE_ASYM),
|
||||
BooleanUtils.toBooleanObject(record.getActive()),
|
||||
Utils.toDateTimeUTC(record.getLastUpdateTime()),
|
||||
record.getLastUpdateUser()));
|
||||
record.getLastUpdateUser(),
|
||||
Utils.getIdsFromString(
|
||||
additionalAttributes.containsKey(SEBClientConfig.ATTR_EXAM_SELECTION)
|
||||
? additionalAttributes.get(SEBClientConfig.ATTR_EXAM_SELECTION).getValue()
|
||||
: null)));
|
||||
}
|
||||
|
||||
private String getEncryptionPassword(final SEBClientConfig sebClientConfig) {
|
||||
|
@ -685,6 +689,21 @@ public class SEBClientConfigDAOImpl implements SEBClientConfigDAO {
|
|||
configId,
|
||||
SEBClientConfig.ATTR_ENCRYPT_CERTIFICATE_ASYM);
|
||||
}
|
||||
|
||||
final Set<Long> selectedExams = sebClientConfig.getSelectedExams();
|
||||
if (selectedExams != null && !selectedExams.isEmpty()) {
|
||||
final String ids = StringUtils.join(selectedExams, Constants.LIST_SEPARATOR);
|
||||
this.additionalAttributesDAO.saveAdditionalAttribute(
|
||||
EntityType.SEB_CLIENT_CONFIGURATION,
|
||||
configId,
|
||||
SEBClientConfig.ATTR_EXAM_SELECTION,
|
||||
ids);
|
||||
} else {
|
||||
this.additionalAttributesDAO.delete(
|
||||
EntityType.SEB_CLIENT_CONFIGURATION,
|
||||
configId,
|
||||
SEBClientConfig.ATTR_EXAM_SELECTION);
|
||||
}
|
||||
}
|
||||
|
||||
private Long disposeSEBClientConfig(final Long pk) {
|
||||
|
|
|
@ -63,5 +63,5 @@ public interface ClientConfigService {
|
|||
boolean checkAccess(SEBClientConfig config);
|
||||
|
||||
@Async(AsyncServiceSpringConfig.EXECUTOR_BEAN_NAME)
|
||||
void initalCheckAccess(SEBClientConfig config);
|
||||
void initialCheckAccess(SEBClientConfig config);
|
||||
}
|
||||
|
|
|
@ -504,7 +504,7 @@ public class ClientConfigServiceImpl implements ClientConfigService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void initalCheckAccess(final SEBClientConfig config) {
|
||||
public void initialCheckAccess(final SEBClientConfig config) {
|
||||
checkAccess(config);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
package ch.ethz.seb.sebserver.webservice.servicelayer.session;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.security.Principal;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
@ -130,9 +131,10 @@ public interface ExamSessionService {
|
|||
/** Gets all currently running Exams for a particular Institution.
|
||||
*
|
||||
* @param institutionId the Institution identifier
|
||||
* @param examSelectionFilter Exam selection filter from SEB connection configuration
|
||||
* @return Result referencing the list of all currently running Exams of the institution or to an error if
|
||||
* happened. */
|
||||
Result<Collection<Exam>> getRunningExamsForInstitution(Long institutionId);
|
||||
Result<Collection<Exam>> getRunningExams(Long institutionId, Predicate<Long> examSelectionFilter);
|
||||
|
||||
/** Gets all currently running Exams for a particular FilterMap.
|
||||
*
|
||||
|
|
|
@ -10,6 +10,7 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.security.Principal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
@ -251,9 +252,10 @@ public class ExamSessionServiceImpl implements ExamSessionService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Result<Collection<Exam>> getRunningExamsForInstitution(final Long institutionId) {
|
||||
public Result<Collection<Exam>> getRunningExams(final Long institutionId, final Predicate<Long> examSelectionFilter) {
|
||||
return this.examDAO.allIdsOfRunning(institutionId)
|
||||
.map(col -> col.stream()
|
||||
.filter(examSelectionFilter)
|
||||
.map(this::getRunningExam)
|
||||
.filter(Result::hasValue)
|
||||
.map(Result::get)
|
||||
|
|
|
@ -11,17 +11,17 @@ package ch.ethz.seb.sebserver.webservice.weblayer.api;
|
|||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.Principal;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.SEBClientConfig;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -132,7 +132,10 @@ public class ExamAPI_V1_Controller {
|
|||
// Crate list of running exams
|
||||
final List<RunningExamInfo> result;
|
||||
if (examId == null) {
|
||||
result = this.examSessionService.getRunningExamsForInstitution(institutionId)
|
||||
|
||||
result = this.examSessionService.getRunningExams(
|
||||
institutionId,
|
||||
getExamSelectionPredicate(principal.getName()))
|
||||
.getOrThrow()
|
||||
.stream()
|
||||
.map(this::createRunningExamInfo)
|
||||
|
@ -161,17 +164,7 @@ public class ExamAPI_V1_Controller {
|
|||
this.executor);
|
||||
}
|
||||
|
||||
private boolean checkConsistency(final RunningExamInfo info) {
|
||||
if (StringUtils.isNotBlank(info.name) &&
|
||||
StringUtils.isNotBlank(info.url) &&
|
||||
StringUtils.isNotBlank(info.examId)) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
log.warn("Invalid running exam detected. Filter out exam : {}", info);
|
||||
return false;
|
||||
}
|
||||
|
||||
@RequestMapping(
|
||||
path = API.EXAM_API_HANDSHAKE_ENDPOINT,
|
||||
|
@ -420,4 +413,31 @@ public class ExamAPI_V1_Controller {
|
|||
.onSuccess(bek -> response.setHeader(API.EXAM_API_EXAM_ALT_BEK, bek));
|
||||
}
|
||||
|
||||
private Predicate<Long> getExamSelectionPredicate(final String clientName) {
|
||||
return this.sebClientConfigDAO
|
||||
.byClientName(clientName)
|
||||
.map(this::getExamSelectionPredicate)
|
||||
.onError(error -> log.warn("Failed to get SEB connection configuration by name: {}", clientName))
|
||||
.getOr(Utils.truePredicate());
|
||||
}
|
||||
|
||||
private Predicate<Long> getExamSelectionPredicate(final SEBClientConfig config) {
|
||||
if (config == null || config.selectedExams.isEmpty()) {
|
||||
return Utils.truePredicate();
|
||||
}
|
||||
return config.getSelectedExams()::contains;
|
||||
}
|
||||
|
||||
private boolean checkConsistency(final RunningExamInfo info) {
|
||||
if (StringUtils.isNotBlank(info.name) &&
|
||||
StringUtils.isNotBlank(info.url) &&
|
||||
StringUtils.isNotBlank(info.examId)) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
log.warn("Invalid running exam detected. Filter out exam : {}", info);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -182,7 +182,7 @@ public class SEBClientConfigController extends ActivatableEntityController<SEBCl
|
|||
protected Result<SEBClientConfig> notifySaved(final SEBClientConfig entity) {
|
||||
if (entity.isActive()) {
|
||||
// try to get access token for SEB client
|
||||
this.sebClientConfigService.initalCheckAccess(entity);
|
||||
this.sebClientConfigService.initialCheckAccess(entity);
|
||||
}
|
||||
return super.notifySaved(entity);
|
||||
}
|
||||
|
|
|
@ -129,6 +129,7 @@ sebserver.form.mandatory.label={0} mandatory
|
|||
sebserver.form.confirm.label=confirm {0}
|
||||
sebserver.form.tablefilter.label={0} table-column filter
|
||||
sebserver.table.column.sort.default.tooltip=Click on the column header to sort the table within this column
|
||||
sebserver.form.multiselect.deselect.tooltip=Please use double-click to deselect selected items.
|
||||
|
||||
sebserver.dialog.confirm.deactivation=Note that there are {0} other entities that belong to this entity.<br/>Those will also be deactivated by deactivating this entity.<br/><br/>Are you sure to deactivate this entity?
|
||||
sebserver.dialog.confirm.deactivation.noDependencies=Are you sure you want to deactivate?
|
||||
|
@ -1033,6 +1034,8 @@ sebserver.clientconfig.form.certificate=Encrypt with Certificate
|
|||
sebserver.clientconfig.form.certificate.tooltip=Choose identity certificate to be used for encrypting the connection configuration
|
||||
sebserver.clientconfig.form.type.async=Use asymmetric-only encryption
|
||||
sebserver.clientconfig.form.type.async.tooltip=Use old asymmetric-only encryption (for SEB < 2.2)
|
||||
sebserver.clientconfig.form.examselection=Exams
|
||||
sebserver.clientconfig.form.examselection.tooltip=List of Exams selected to work with this Connection Configuration.
|
||||
|
||||
sebserver.clientconfig.form.credentials.title=Client Credentials of Connection Configuration
|
||||
sebserver.clientconfig.form.credentials.info=A SEB client that loads this connection configuration<br/>uses the following credentials to securely connect to the SEB Server.
|
||||
|
|
|
@ -138,7 +138,8 @@ public class ModelObjectJSONGenerator {
|
|||
false,
|
||||
true,
|
||||
DateTime.now(),
|
||||
"user123");
|
||||
"user123",
|
||||
null);
|
||||
System.out.println(domainObject.getClass().getSimpleName() + ":");
|
||||
System.out.println(writerWithDefaultPrettyPrinter.writeValueAsString(domainObject));
|
||||
|
||||
|
|
|
@ -128,6 +128,7 @@ public class ClientConfigTest extends GuiIntegrationTest {
|
|||
false,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null))
|
||||
.call();
|
||||
|
||||
|
@ -161,6 +162,7 @@ public class ClientConfigTest extends GuiIntegrationTest {
|
|||
false,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null))
|
||||
.call()
|
||||
.getOrThrow();
|
||||
|
|
|
@ -12,6 +12,7 @@ import static org.junit.Assert.*;
|
|||
|
||||
import java.util.Collection;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Order;
|
||||
|
@ -61,7 +62,7 @@ public class ExamProctoringRoomServiceTest extends AdministrationAPIIntegrationT
|
|||
@Order(1)
|
||||
public void test01_checkExamRunning() {
|
||||
final Result<Collection<Exam>> runningExamsForInstitution =
|
||||
this.examSessionService.getRunningExamsForInstitution(1L);
|
||||
this.examSessionService.getRunningExams(1L, Utils.truePredicate());
|
||||
assertFalse(runningExamsForInstitution.hasError());
|
||||
final Collection<Exam> collection = runningExamsForInstitution.get();
|
||||
assertFalse(collection.isEmpty());
|
||||
|
|
Loading…
Reference in a new issue