SEBSERV-376 finished up
This commit is contained in:
		
							parent
							
								
									504c2a0843
								
							
						
					
					
						commit
						e85f2acfd2
					
				
					 20 changed files with 245 additions and 143 deletions
				
			
		| 
						 | 
				
			
			@ -27,8 +27,8 @@ public class AllowedSEBVersion {
 | 
			
		|||
    public final int major;
 | 
			
		||||
    public final int minor;
 | 
			
		||||
    public final int patch;
 | 
			
		||||
    public final boolean alianceEdition;
 | 
			
		||||
    public final boolean minimal;
 | 
			
		||||
    public boolean alianceEdition;
 | 
			
		||||
    public boolean minimal;
 | 
			
		||||
    public final boolean isValidFormat;
 | 
			
		||||
 | 
			
		||||
    public AllowedSEBVersion(final String wholeVersionString) {
 | 
			
		||||
| 
						 | 
				
			
			@ -61,29 +61,43 @@ public class AllowedSEBVersion {
 | 
			
		|||
            valid = false;
 | 
			
		||||
        }
 | 
			
		||||
        this.minor = num;
 | 
			
		||||
        if (split.length >= 3) {
 | 
			
		||||
            try {
 | 
			
		||||
                num = Integer.valueOf(split[3]);
 | 
			
		||||
            } catch (final Exception e) {
 | 
			
		||||
                num = 0;
 | 
			
		||||
                if (split[3].equals(ALIANCE_EDITION_IDENTIFIER)) {
 | 
			
		||||
                    this.alianceEdition = true;
 | 
			
		||||
                } else if (split[3].equals(MINIMAL_IDENTIFIER)) {
 | 
			
		||||
                    this.minimal = true;
 | 
			
		||||
                } else {
 | 
			
		||||
                    valid = false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            num = 0;
 | 
			
		||||
        }
 | 
			
		||||
        this.patch = num;
 | 
			
		||||
 | 
			
		||||
        if (split.length > 4 && ALIANCE_EDITION_IDENTIFIER.equalsIgnoreCase(split[4])) {
 | 
			
		||||
        if (valid && split.length > 4) {
 | 
			
		||||
            if (!this.alianceEdition && split[4].equals(ALIANCE_EDITION_IDENTIFIER)) {
 | 
			
		||||
                this.alianceEdition = true;
 | 
			
		||||
            if (split.length > 5 && MINIMAL_IDENTIFIER.equalsIgnoreCase(split[5])) {
 | 
			
		||||
            } else if (!this.minimal && split[4].equals(MINIMAL_IDENTIFIER)) {
 | 
			
		||||
                this.minimal = true;
 | 
			
		||||
            } else {
 | 
			
		||||
                this.minimal = false;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            this.alianceEdition = false;
 | 
			
		||||
            if (split.length > 4 && MINIMAL_IDENTIFIER.equalsIgnoreCase(split[4])) {
 | 
			
		||||
                this.minimal = true;
 | 
			
		||||
            } else {
 | 
			
		||||
                this.minimal = false;
 | 
			
		||||
                valid = false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (valid && split.length > 5) {
 | 
			
		||||
            if (!this.alianceEdition && split[5].equals(ALIANCE_EDITION_IDENTIFIER)) {
 | 
			
		||||
                this.alianceEdition = true;
 | 
			
		||||
            } else if (!this.minimal && split[5].equals(MINIMAL_IDENTIFIER)) {
 | 
			
		||||
                this.minimal = true;
 | 
			
		||||
            } else {
 | 
			
		||||
                valid = false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        this.isValidFormat = valid;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -91,9 +105,12 @@ public class AllowedSEBVersion {
 | 
			
		|||
        if (Objects.equals(this.osTypeString, clientVersion.osTypeString)) {
 | 
			
		||||
            if (this.minimal) {
 | 
			
		||||
                // check greater or equals minimum version
 | 
			
		||||
                return this.major <= clientVersion.major ||
 | 
			
		||||
                        this.minor <= clientVersion.minor ||
 | 
			
		||||
                        this.patch <= clientVersion.patch;
 | 
			
		||||
                return this.major < clientVersion.major
 | 
			
		||||
                        || (this.major == clientVersion.major
 | 
			
		||||
                                && this.minor < clientVersion.minor)
 | 
			
		||||
                        || (this.major == clientVersion.major
 | 
			
		||||
                                && this.minor == clientVersion.minor
 | 
			
		||||
                                && this.patch <= clientVersion.patch);
 | 
			
		||||
            } else {
 | 
			
		||||
                // check exact match
 | 
			
		||||
                return this.major == clientVersion.major &&
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -442,13 +442,13 @@ public final class ClientConnection implements GrantEntity {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    private String getSEBInfo(final String seb_version) {
 | 
			
		||||
        return (seb_version != null) ? "SEBV: " + seb_version : Constants.EMPTY_NOTE;
 | 
			
		||||
        return (seb_version != null) ? "SEB:" + seb_version : Constants.EMPTY_NOTE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private String getOSInfo(final String seb_os_name) {
 | 
			
		||||
        if (seb_os_name != null) {
 | 
			
		||||
            final String[] split = StringUtils.split(seb_os_name, Constants.LIST_SEPARATOR);
 | 
			
		||||
            return "OSV: " + split[0];
 | 
			
		||||
            return " OS:" + split[0];
 | 
			
		||||
        }
 | 
			
		||||
        return Constants.EMPTY_NOTE;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,12 +24,13 @@ public class ClientMonitoringData implements ClientMonitoringDataView {
 | 
			
		|||
    public final Long id;
 | 
			
		||||
    public final ConnectionStatus status;
 | 
			
		||||
    public final Map<Long, String> indicatorVals;
 | 
			
		||||
    public final Integer notificationFlag;
 | 
			
		||||
 | 
			
		||||
    public final int notificationFlag;
 | 
			
		||||
    public final boolean missingPing;
 | 
			
		||||
    public final boolean grantChecked;
 | 
			
		||||
    public final boolean grantDenied;
 | 
			
		||||
    public final boolean pendingNotification;
 | 
			
		||||
    public final boolean sebVersionDenied;
 | 
			
		||||
 | 
			
		||||
    @JsonCreator
 | 
			
		||||
    public ClientMonitoringData(
 | 
			
		||||
| 
						 | 
				
			
			@ -41,11 +42,12 @@ public class ClientMonitoringData implements ClientMonitoringDataView {
 | 
			
		|||
        this.id = id;
 | 
			
		||||
        this.status = status;
 | 
			
		||||
        this.indicatorVals = indicatorVals;
 | 
			
		||||
        this.notificationFlag = notificationFlag;
 | 
			
		||||
        this.notificationFlag = notificationFlag != null ? notificationFlag : -1;
 | 
			
		||||
        this.missingPing = notificationFlag != null && (notificationFlag & FLAG_MISSING_PING) > 0;
 | 
			
		||||
        this.grantChecked = notificationFlag == null || (notificationFlag & FLAG_GRANT_NOT_CHECKED) == 0;
 | 
			
		||||
        this.grantDenied = notificationFlag != null && (notificationFlag & FLAG_GRANT_DENIED) > 0;
 | 
			
		||||
        this.pendingNotification = notificationFlag != null && (notificationFlag & FLAG_PENDING_NOTIFICATION) > 0;
 | 
			
		||||
        this.sebVersionDenied = notificationFlag != null && (notificationFlag & FLAG_INVALID_SEB_VERSION) > 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -100,6 +100,7 @@ public class ResourceService {
 | 
			
		|||
    private static final String MISSING_CLIENT_PING_NAME_KEY = "MISSING_PING";
 | 
			
		||||
    private static final String DENIED_CLIENT_SEC_GRANT_NAME_KEY = "GRANT_DENIED";
 | 
			
		||||
    private static final String MISSING_CLIENT_SEC_GRANT_NAME_KEY = "MISSING_GRANT";
 | 
			
		||||
    private static final String DENIED_CLIENT_SEB_VERSION_NAME_KEY = "SEB_VERSION_DENIED";
 | 
			
		||||
 | 
			
		||||
    public static final Comparator<Tuple<String>> RESOURCE_COMPARATOR = Comparator.comparing(t -> t._2);
 | 
			
		||||
    public static final Comparator<Tuple3<String>> RESOURCE_COMPARATOR_TUPLE_3 = Comparator.comparing(t -> t._2);
 | 
			
		||||
| 
						 | 
				
			
			@ -638,6 +639,7 @@ public class ResourceService {
 | 
			
		|||
        final String grantMissingText = this.i18nSupport.getText(
 | 
			
		||||
                SEB_CONNECTION_STATUS_KEY_PREFIX + MISSING_CLIENT_SEC_GRANT_NAME_KEY,
 | 
			
		||||
                MISSING_CLIENT_SEC_GRANT_NAME_KEY);
 | 
			
		||||
 | 
			
		||||
        final EnumMap<ConnectionStatus, String> localizedNames = new EnumMap<>(ConnectionStatus.class);
 | 
			
		||||
        Arrays.asList(ConnectionStatus.values()).stream().forEach(state -> localizedNames.put(state, this.i18nSupport
 | 
			
		||||
                .getText(SEB_CONNECTION_STATUS_KEY_PREFIX + state.name(), state.name())));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -80,7 +80,8 @@ public class TextFieldListBuilder extends AbstractTableFieldBuilder {
 | 
			
		|||
                innerGrid,
 | 
			
		||||
                new LocTextKey(attributeNameKey),
 | 
			
		||||
                3,
 | 
			
		||||
                this.widgetFactory);
 | 
			
		||||
                this.widgetFactory,
 | 
			
		||||
                !viewContext.isReadonly());
 | 
			
		||||
        WidgetFactory.setTestId(textListInput, attributeNameKey);
 | 
			
		||||
        textListInput.setLayoutData(gridData);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -179,6 +179,17 @@ public class ClientConnectionDetails implements MonitoringEntry {
 | 
			
		|||
        return this.grantDenied;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int incidentFlag() {
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean sebVersionDenied() {
 | 
			
		||||
        return this.connectionData.clientConnection.clientVersionGranted != null &&
 | 
			
		||||
                !this.connectionData.clientConnection.clientVersionGranted;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean showNoGrantCheckApplied() {
 | 
			
		||||
        return this.checkSecurityGrant;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -94,6 +94,7 @@ public final class ClientConnectionTable implements FullPageMonitoringGUIUpdate
 | 
			
		|||
    private final PageService pageService;
 | 
			
		||||
    private final Exam exam;
 | 
			
		||||
    private final boolean checkSecurityGrant;
 | 
			
		||||
    private final boolean checkSEBVersion;
 | 
			
		||||
    private final boolean distributedSetup;
 | 
			
		||||
 | 
			
		||||
    private final Map<Long, IndicatorData> indicatorMapping;
 | 
			
		||||
| 
						 | 
				
			
			@ -131,6 +132,7 @@ public final class ClientConnectionTable implements FullPageMonitoringGUIUpdate
 | 
			
		|||
        this.exam = exam;
 | 
			
		||||
        this.checkSecurityGrant = BooleanUtils.toBoolean(
 | 
			
		||||
                exam.additionalAttributes.get(Exam.ADDITIONAL_ATTR_SIGNATURE_KEY_CHECK_ENABLED));
 | 
			
		||||
        this.checkSEBVersion = exam.additionalAttributes.containsKey(Exam.ADDITIONAL_ATTR_ALLOWED_SEB_VERSIONS);
 | 
			
		||||
        this.distributedSetup = distributedSetup;
 | 
			
		||||
 | 
			
		||||
        final WidgetFactory widgetFactory = pageService.getWidgetFactory();
 | 
			
		||||
| 
						 | 
				
			
			@ -488,6 +490,16 @@ public final class ClientConnectionTable implements FullPageMonitoringGUIUpdate
 | 
			
		|||
            return this.monitoringData.grantDenied;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public boolean sebVersionDenied() {
 | 
			
		||||
            return this.monitoringData.sebVersionDenied;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public int incidentFlag() {
 | 
			
		||||
            return this.monitoringData.notificationFlag;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public boolean showNoGrantCheckApplied() {
 | 
			
		||||
            return ClientConnectionTable.this.checkSecurityGrant;
 | 
			
		||||
| 
						 | 
				
			
			@ -506,20 +518,22 @@ public final class ClientConnectionTable implements FullPageMonitoringGUIUpdate
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        private void updateData(final TableItem tableItem) {
 | 
			
		||||
            tableItem.setText(0, getConnectionIdentifier());
 | 
			
		||||
            int row = 0;
 | 
			
		||||
            tableItem.setText(row++, getConnectionIdentifier());
 | 
			
		||||
            if (ClientConnectionTable.this.hasClientGroups) {
 | 
			
		||||
                tableItem.setText(1, getGroupInfo());
 | 
			
		||||
                tableItem.setText(2, getConnectionInfo());
 | 
			
		||||
                tableItem.setText(
 | 
			
		||||
                        3,
 | 
			
		||||
                        ClientConnectionTable.this.localizedClientConnectionStatusNameFunction.apply(this));
 | 
			
		||||
            } else {
 | 
			
		||||
                tableItem.setText(1, getConnectionInfo());
 | 
			
		||||
                tableItem.setText(
 | 
			
		||||
                        2,
 | 
			
		||||
                        ClientConnectionTable.this.localizedClientConnectionStatusNameFunction.apply(this));
 | 
			
		||||
                tableItem.setText(row++, getGroupInfo());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            tableItem.setText(row++, getConnectionInfo());
 | 
			
		||||
            if (ClientConnectionTable.this.checkSEBVersion) {
 | 
			
		||||
                if (sebVersionDenied()) {
 | 
			
		||||
                    tableItem.setBackground(row - 1, ClientConnectionTable.this.colorData.color2);
 | 
			
		||||
                } else {
 | 
			
		||||
                    tableItem.setBackground(row - 1, ClientConnectionTable.this.colorData.color1);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            tableItem.setText(
 | 
			
		||||
                    row++,
 | 
			
		||||
                    ClientConnectionTable.this.localizedClientConnectionStatusNameFunction.apply(this));
 | 
			
		||||
            if (this.monitoringData != null) {
 | 
			
		||||
                updateConnectionStatusColor(tableItem);
 | 
			
		||||
                updateNotifications(tableItem);
 | 
			
		||||
| 
						 | 
				
			
			@ -546,9 +560,11 @@ public final class ClientConnectionTable implements FullPageMonitoringGUIUpdate
 | 
			
		|||
            if (BooleanUtils.isTrue(this.monitoringData.pendingNotification)) {
 | 
			
		||||
                tableItem.setImage(0,
 | 
			
		||||
                        WidgetFactory.ImageIcon.NOTIFICATION.getImage(ClientConnectionTable.this.table.getDisplay()));
 | 
			
		||||
                tableItem.setBackground(0, ClientConnectionTable.this.colorData.color2);
 | 
			
		||||
            } else {
 | 
			
		||||
                if (tableItem.getImage(0) != null) {
 | 
			
		||||
                    tableItem.setImage(0, null);
 | 
			
		||||
                    tableItem.setBackground(0, ClientConnectionTable.this.colorData.color1);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -745,6 +761,7 @@ public final class ClientConnectionTable implements FullPageMonitoringGUIUpdate
 | 
			
		|||
        private ClientConnectionTable getOuterType() {
 | 
			
		||||
            return ClientConnectionTable.this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void fetchStaticClientConnectionData() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,7 +14,7 @@ import org.eclipse.swt.widgets.Display;
 | 
			
		|||
 | 
			
		||||
import ch.ethz.seb.sebserver.gbl.Constants;
 | 
			
		||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection.ConnectionStatus;
 | 
			
		||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnectionData;
 | 
			
		||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientMonitoringDataView;
 | 
			
		||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
 | 
			
		||||
 | 
			
		||||
public class ColorData {
 | 
			
		||||
| 
						 | 
				
			
			@ -42,10 +42,21 @@ public class ColorData {
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        switch (status) {
 | 
			
		||||
            case ACTIVE:
 | 
			
		||||
                return (entry.grantChecked() && entry.grantDenied())
 | 
			
		||||
                        ? this.color3 : (entry.hasMissingPing())
 | 
			
		||||
                                ? this.color2 : this.color1;
 | 
			
		||||
            case CONNECTION_REQUESTED:
 | 
			
		||||
            case AUTHENTICATED:
 | 
			
		||||
            case ACTIVE: {
 | 
			
		||||
                final int incidentFlag = entry.incidentFlag();
 | 
			
		||||
                if (incidentFlag > 0) {
 | 
			
		||||
                    if ((incidentFlag & ClientMonitoringDataView.FLAG_GRANT_DENIED) > 0) {
 | 
			
		||||
                        return this.color3;
 | 
			
		||||
                    }
 | 
			
		||||
                    if ((incidentFlag & (ClientMonitoringDataView.FLAG_GRANT_NOT_CHECKED
 | 
			
		||||
                            | ClientMonitoringDataView.FLAG_MISSING_PING)) > 0) {
 | 
			
		||||
                        return this.color2;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                return this.color1;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                return this.defaultColor;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -55,41 +66,25 @@ public class ColorData {
 | 
			
		|||
        return Utils.darkColorContrast(statusColor.getRGB()) ? this.darkColor : this.lightColor;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int statusWeight(final ClientConnectionData connectionData) {
 | 
			
		||||
        if (connectionData == null) {
 | 
			
		||||
            return 100;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        switch (connectionData.clientConnection.status) {
 | 
			
		||||
            case CONNECTION_REQUESTED:
 | 
			
		||||
            case AUTHENTICATED:
 | 
			
		||||
                return 1;
 | 
			
		||||
            case ACTIVE:
 | 
			
		||||
                return (connectionData.clientConnection.securityCheckGranted)
 | 
			
		||||
                        ? -1 : (connectionData.missingPing)
 | 
			
		||||
                                ? 0 : 2;
 | 
			
		||||
            case CLOSED:
 | 
			
		||||
                return 3;
 | 
			
		||||
            default:
 | 
			
		||||
                return 10;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int statusWeight(final MonitoringEntry entry) {
 | 
			
		||||
        if (entry == null) {
 | 
			
		||||
            return 100;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        final Boolean grantDenied = entry.grantDenied();
 | 
			
		||||
        switch (entry.getStatus()) {
 | 
			
		||||
            case CONNECTION_REQUESTED:
 | 
			
		||||
            case AUTHENTICATED:
 | 
			
		||||
            case AUTHENTICATED: {
 | 
			
		||||
                if (entry.incidentFlag() > 0) {
 | 
			
		||||
                    return -1;
 | 
			
		||||
                }
 | 
			
		||||
                return 1;
 | 
			
		||||
            case ACTIVE:
 | 
			
		||||
                return (grantDenied == null)
 | 
			
		||||
                        ? -1 : (grantDenied)
 | 
			
		||||
                                ? -2 : (entry.hasMissingPing())
 | 
			
		||||
                                        ? 0 : 2;
 | 
			
		||||
            }
 | 
			
		||||
            case ACTIVE: {
 | 
			
		||||
                if (entry.incidentFlag() > 0) {
 | 
			
		||||
                    return -1;
 | 
			
		||||
                }
 | 
			
		||||
                return 2;
 | 
			
		||||
            }
 | 
			
		||||
            case CLOSED:
 | 
			
		||||
                return 4;
 | 
			
		||||
            default:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,12 +14,16 @@ public interface MonitoringEntry {
 | 
			
		|||
 | 
			
		||||
    ConnectionStatus getStatus();
 | 
			
		||||
 | 
			
		||||
    int incidentFlag();
 | 
			
		||||
 | 
			
		||||
    boolean hasMissingPing();
 | 
			
		||||
 | 
			
		||||
    boolean grantChecked();
 | 
			
		||||
 | 
			
		||||
    boolean grantDenied();
 | 
			
		||||
 | 
			
		||||
    boolean sebVersionDenied();
 | 
			
		||||
 | 
			
		||||
    boolean showNoGrantCheckApplied();
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -12,7 +12,6 @@ import java.util.ArrayList;
 | 
			
		|||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.lang3.StringUtils;
 | 
			
		||||
import org.eclipse.rap.rwt.RWT;
 | 
			
		||||
import org.eclipse.swt.SWT;
 | 
			
		||||
import org.eclipse.swt.layout.GridData;
 | 
			
		||||
import org.eclipse.swt.layout.GridLayout;
 | 
			
		||||
| 
						 | 
				
			
			@ -26,7 +25,6 @@ import org.eclipse.swt.widgets.Text;
 | 
			
		|||
import ch.ethz.seb.sebserver.gbl.Constants;
 | 
			
		||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
 | 
			
		||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
 | 
			
		||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant;
 | 
			
		||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.ImageIcon;
 | 
			
		||||
 | 
			
		||||
public class TextListInput extends Composite {
 | 
			
		||||
| 
						 | 
				
			
			@ -44,16 +42,20 @@ public class TextListInput extends Composite {
 | 
			
		|||
 | 
			
		||||
    private Listener valueChangeEventListener = null;
 | 
			
		||||
 | 
			
		||||
    private boolean isEditable = true;
 | 
			
		||||
 | 
			
		||||
    public TextListInput(
 | 
			
		||||
            final Composite parent,
 | 
			
		||||
            final LocTextKey nameKey,
 | 
			
		||||
            final int initialSize,
 | 
			
		||||
            final WidgetFactory widgetFactory) {
 | 
			
		||||
            final WidgetFactory widgetFactory,
 | 
			
		||||
            final boolean editable) {
 | 
			
		||||
 | 
			
		||||
        super(parent, SWT.NONE);
 | 
			
		||||
        this.nameKey = nameKey;
 | 
			
		||||
        this.initialSize = initialSize;
 | 
			
		||||
        this.widgetFactory = widgetFactory;
 | 
			
		||||
        this.isEditable = editable;
 | 
			
		||||
 | 
			
		||||
        // main grid layout
 | 
			
		||||
        GridLayout gridLayout = new GridLayout(1, false);
 | 
			
		||||
| 
						 | 
				
			
			@ -93,9 +95,6 @@ public class TextListInput extends Composite {
 | 
			
		|||
        this.addAction.setLayoutData(gridData);
 | 
			
		||||
 | 
			
		||||
        this.content = header;
 | 
			
		||||
        for (int i = 0; i < initialSize; i++) {
 | 
			
		||||
            addRow(null);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void addListener(final Listener valueChangeEventListener) {
 | 
			
		||||
| 
						 | 
				
			
			@ -123,7 +122,6 @@ public class TextListInput extends Composite {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    public void setValue(final String value) {
 | 
			
		||||
        System.out.println("************ value: " + value);
 | 
			
		||||
        if (StringUtils.isBlank(value)) {
 | 
			
		||||
            // clear rows
 | 
			
		||||
            new ArrayList<>(this.list).stream().forEach(row -> row.deleteRow());
 | 
			
		||||
| 
						 | 
				
			
			@ -148,8 +146,9 @@ public class TextListInput extends Composite {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    public void setEditable(final boolean b) {
 | 
			
		||||
        this.isEditable = b;
 | 
			
		||||
        this.addAction.setEnabled(b);
 | 
			
		||||
        this.list.stream().forEach(row -> row.setEditable(b));
 | 
			
		||||
        this.setValue(getValue());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private final class Row {
 | 
			
		||||
| 
						 | 
				
			
			@ -162,9 +161,10 @@ public class TextListInput extends Composite {
 | 
			
		|||
                    TextListInput.this.content,
 | 
			
		||||
                    TextListInput.this.nameKey);
 | 
			
		||||
            GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, true);
 | 
			
		||||
            this.textInput.setEditable(TextListInput.this.isEditable);
 | 
			
		||||
            if (TextListInput.this.isEditable) {
 | 
			
		||||
                this.textInput.setLayoutData(gridData);
 | 
			
		||||
                this.addListener();
 | 
			
		||||
 | 
			
		||||
                this.deleteButton = TextListInput.this.widgetFactory.imageButton(
 | 
			
		||||
                        ImageIcon.REMOVE_BOX,
 | 
			
		||||
                        TextListInput.this.content,
 | 
			
		||||
| 
						 | 
				
			
			@ -173,6 +173,11 @@ public class TextListInput extends Composite {
 | 
			
		|||
                gridData = new GridData(SWT.RIGHT, SWT.CENTER, false, true);
 | 
			
		||||
                gridData.widthHint = ACTION_COLUMN_WIDTH;
 | 
			
		||||
                this.deleteButton.setLayoutData(gridData);
 | 
			
		||||
                this.deleteButton.setEnabled(TextListInput.this.isEditable);
 | 
			
		||||
            } else {
 | 
			
		||||
                this.deleteButton = null;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void addListener() {
 | 
			
		||||
| 
						 | 
				
			
			@ -185,20 +190,24 @@ public class TextListInput extends Composite {
 | 
			
		|||
        public void deleteRow() {
 | 
			
		||||
            TextListInput.this.list.remove(this);
 | 
			
		||||
            this.textInput.dispose();
 | 
			
		||||
            if (this.deleteButton != null) {
 | 
			
		||||
                this.deleteButton.dispose();
 | 
			
		||||
            }
 | 
			
		||||
            TextListInput.this.content.getParent().getParent().layout(true, true);
 | 
			
		||||
            if (TextListInput.this.valueChangeEventListener != null) {
 | 
			
		||||
                TextListInput.this.valueChangeEventListener.handleEvent(null);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void setEditable(final boolean e) {
 | 
			
		||||
            this.textInput.setEditable(e);
 | 
			
		||||
            this.textInput.setData(
 | 
			
		||||
                    RWT.CUSTOM_VARIANT,
 | 
			
		||||
                    e ? null : CustomVariant.CONFIG_INPUT_READONLY.key);
 | 
			
		||||
            this.deleteButton.setEnabled(e);
 | 
			
		||||
        }
 | 
			
		||||
//        public void setEditable(final boolean e) {
 | 
			
		||||
//            this.textInput.setEditable(e);
 | 
			
		||||
//            this.textInput.setData(
 | 
			
		||||
//                    RWT.CUSTOM_VARIANT,
 | 
			
		||||
//                    e ? null : CustomVariant.CONFIG_INPUT_READONLY.key);
 | 
			
		||||
//            if (this.deleteButton != null) {
 | 
			
		||||
//                this.deleteButton.setEnabled(e);
 | 
			
		||||
//            }
 | 
			
		||||
//        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -104,6 +104,11 @@ public interface ExamAdminService {
 | 
			
		|||
        return isProctoringEnabled(exam.id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** Updates needed additional attributes from assigned exam configuration for the exam
 | 
			
		||||
     *
 | 
			
		||||
     * @param examId The exam identifier */
 | 
			
		||||
    void updateAdditionalExamConfigAttributes(final Long examId);
 | 
			
		||||
 | 
			
		||||
    /** This indicates if proctoring is set and enabled for a certain exam.
 | 
			
		||||
     *
 | 
			
		||||
     * @param examId the exam identifier
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,6 +12,7 @@ public interface ExamConfigurationValueService {
 | 
			
		|||
 | 
			
		||||
    public static final String CONFIG_ATTR_NAME_QUIT_LINK = "quitURL";
 | 
			
		||||
    public static final String CONFIG_ATTR_NAME_QUIT_SECRET = "hashedQuitPassword";
 | 
			
		||||
    public static final String CONFIG_ATTR_NAME_ALLOWED_SEB_VERSION = "sebAllowedVersions";
 | 
			
		||||
 | 
			
		||||
    /** Get the actual SEB settings attribute value for the exam configuration mapped as default configuration
 | 
			
		||||
     * to the given exam
 | 
			
		||||
| 
						 | 
				
			
			@ -19,7 +20,21 @@ public interface ExamConfigurationValueService {
 | 
			
		|||
     * @param examId The exam identifier
 | 
			
		||||
     * @param configAttributeName The name of the SEB settings attribute
 | 
			
		||||
     * @return The current value of the above SEB settings attribute and given exam. */
 | 
			
		||||
    String getMappedDefaultConfigAttributeValue(Long examId, String configAttributeName);
 | 
			
		||||
    default String getMappedDefaultConfigAttributeValue(final Long examId, final String configAttributeName) {
 | 
			
		||||
        return getMappedDefaultConfigAttributeValue(examId, configAttributeName, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** Get the actual SEB settings attribute value for the exam configuration mapped as default configuration
 | 
			
		||||
     * to the given exam
 | 
			
		||||
     *
 | 
			
		||||
     * @param examId The exam identifier
 | 
			
		||||
     * @param configAttributeName The name of the SEB settings attribute
 | 
			
		||||
     * @param The default value that is given back if there is no value from configuration
 | 
			
		||||
     * @return The current value of the above SEB settings attribute and given exam. */
 | 
			
		||||
    String getMappedDefaultConfigAttributeValue(
 | 
			
		||||
            Long examId,
 | 
			
		||||
            String configAttributeName,
 | 
			
		||||
            String defaultValue);
 | 
			
		||||
 | 
			
		||||
    /** Get the quitPassword SEB Setting from the Exam Configuration that is applied to the given exam.
 | 
			
		||||
     *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,6 +46,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationNodeDAO;
 | 
			
		|||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamConfigurationMapDAO;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamDAO;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.exam.ExamAdminService;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.exam.ExamConfigurationValueService;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.exam.ProctoringAdminService;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPIService;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplate;
 | 
			
		||||
| 
						 | 
				
			
			@ -67,6 +68,7 @@ public class ExamAdminServiceImpl implements ExamAdminService {
 | 
			
		|||
    private final LmsAPIService lmsAPIService;
 | 
			
		||||
    private final boolean appSignatureKeyEnabled;
 | 
			
		||||
    private final int defaultNumericalTrustThreshold;
 | 
			
		||||
    private final ExamConfigurationValueService examConfigurationValueService;
 | 
			
		||||
 | 
			
		||||
    protected ExamAdminServiceImpl(
 | 
			
		||||
            final ExamDAO examDAO,
 | 
			
		||||
| 
						 | 
				
			
			@ -75,6 +77,7 @@ public class ExamAdminServiceImpl implements ExamAdminService {
 | 
			
		|||
            final ConfigurationNodeDAO configurationNodeDAO,
 | 
			
		||||
            final ExamConfigurationMapDAO examConfigurationMapDAO,
 | 
			
		||||
            final LmsAPIService lmsAPIService,
 | 
			
		||||
            final ExamConfigurationValueService examConfigurationValueService,
 | 
			
		||||
            final @Value("${sebserver.webservice.api.admin.exam.app.signature.key.enabled:false}") boolean appSignatureKeyEnabled,
 | 
			
		||||
            final @Value("${sebserver.webservice.api.admin.exam.app.signature.key.numerical.threshold:2}") int defaultNumericalTrustThreshold) {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -84,6 +87,7 @@ public class ExamAdminServiceImpl implements ExamAdminService {
 | 
			
		|||
        this.configurationNodeDAO = configurationNodeDAO;
 | 
			
		||||
        this.examConfigurationMapDAO = examConfigurationMapDAO;
 | 
			
		||||
        this.lmsAPIService = lmsAPIService;
 | 
			
		||||
        this.examConfigurationValueService = examConfigurationValueService;
 | 
			
		||||
        this.appSignatureKeyEnabled = appSignatureKeyEnabled;
 | 
			
		||||
        this.defaultNumericalTrustThreshold = defaultNumericalTrustThreshold;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -198,6 +202,30 @@ public class ExamAdminServiceImpl implements ExamAdminService {
 | 
			
		|||
                .onError(error -> log.error("Failed to check SEB restriction: ", error));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void updateAdditionalExamConfigAttributes(final Long examId) {
 | 
			
		||||
        try {
 | 
			
		||||
            final String allowedSEBVersion = this.examConfigurationValueService
 | 
			
		||||
                    .getAllowedSEBVersion(examId);
 | 
			
		||||
 | 
			
		||||
            if (StringUtils.isNotBlank(allowedSEBVersion)) {
 | 
			
		||||
                this.additionalAttributesDAO.saveAdditionalAttribute(
 | 
			
		||||
                        EntityType.EXAM,
 | 
			
		||||
                        examId, Exam.ADDITIONAL_ATTR_ALLOWED_SEB_VERSIONS,
 | 
			
		||||
                        allowedSEBVersion)
 | 
			
		||||
                        .getOrThrow();
 | 
			
		||||
            } else {
 | 
			
		||||
                this.additionalAttributesDAO.delete(
 | 
			
		||||
                        EntityType.EXAM,
 | 
			
		||||
                        examId, Exam.ADDITIONAL_ATTR_ALLOWED_SEB_VERSIONS);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } catch (final Exception e) {
 | 
			
		||||
            log.error("Unexpected error while trying to save additional Exam Configuration settings for exam: {}",
 | 
			
		||||
                    examId, e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Result<ProctoringServiceSettings> getProctoringServiceSettings(final Long examId) {
 | 
			
		||||
        return this.proctoringAdminService.getProctoringSettings(new EntityKey(examId, EntityType.EXAM));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -50,7 +50,11 @@ public class ExamConfigurationValueServiceImpl implements ExamConfigurationValue
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getMappedDefaultConfigAttributeValue(final Long examId, final String configAttributeName) {
 | 
			
		||||
    public String getMappedDefaultConfigAttributeValue(
 | 
			
		||||
            final Long examId,
 | 
			
		||||
            final String configAttributeName,
 | 
			
		||||
            final String defaultValue) {
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
 | 
			
		||||
            final Long configId = this.examConfigurationMapDAO
 | 
			
		||||
| 
						 | 
				
			
			@ -62,7 +66,7 @@ public class ExamConfigurationValueServiceImpl implements ExamConfigurationValue
 | 
			
		|||
                    .getOr(null);
 | 
			
		||||
 | 
			
		||||
            if (configId == null) {
 | 
			
		||||
                return null;
 | 
			
		||||
                return defaultValue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            final Long attrId = this.configurationAttributeDAO
 | 
			
		||||
| 
						 | 
				
			
			@ -73,11 +77,18 @@ public class ExamConfigurationValueServiceImpl implements ExamConfigurationValue
 | 
			
		|||
 | 
			
		||||
            return this.configurationValueDAO
 | 
			
		||||
                    .getConfigAttributeValue(configId, attrId)
 | 
			
		||||
                    .getOrThrow();
 | 
			
		||||
                    .onError(error -> log.warn(
 | 
			
		||||
                            "Failed to get exam config attribute: {} {} error: {}",
 | 
			
		||||
                            examId,
 | 
			
		||||
                            configAttributeName,
 | 
			
		||||
                            error.getMessage()))
 | 
			
		||||
                    .getOr(defaultValue);
 | 
			
		||||
 | 
			
		||||
        } catch (final Exception e) {
 | 
			
		||||
            if (defaultValue == null) {
 | 
			
		||||
                log.error("Unexpected error while trying to extract SEB settings attribute value:", e);
 | 
			
		||||
            return null;
 | 
			
		||||
            }
 | 
			
		||||
            return defaultValue;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -130,10 +141,10 @@ public class ExamConfigurationValueServiceImpl implements ExamConfigurationValue
 | 
			
		|||
 | 
			
		||||
            return getMappedDefaultConfigAttributeValue(
 | 
			
		||||
                    examId,
 | 
			
		||||
                    CONFIG_ATTR_NAME_QUIT_LINK);
 | 
			
		||||
                    CONFIG_ATTR_NAME_ALLOWED_SEB_VERSION,
 | 
			
		||||
                    StringUtils.EMPTY);
 | 
			
		||||
 | 
			
		||||
        } catch (final Exception e) {
 | 
			
		||||
            log.error("Failed to get SEB restriction with quit link: ", e);
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -153,7 +153,8 @@ public class ClientConnectionDataInternal extends ClientConnectionData {
 | 
			
		|||
                    | (isMissingPing() ? ClientMonitoringDataView.FLAG_MISSING_PING : 0)
 | 
			
		||||
                    | (isPendingNotification() ? ClientMonitoringDataView.FLAG_PENDING_NOTIFICATION : 0)
 | 
			
		||||
                    | (!isGrantChecked() ? ClientMonitoringDataView.FLAG_GRANT_NOT_CHECKED : 0)
 | 
			
		||||
                    | (isGrantDenied() ? ClientMonitoringDataView.FLAG_GRANT_DENIED : 0);
 | 
			
		||||
                    | (isGrantDenied() ? ClientMonitoringDataView.FLAG_GRANT_DENIED : 0)
 | 
			
		||||
                    | (isSEBVersionDenied() ? ClientMonitoringDataView.FLAG_INVALID_SEB_VERSION : 0);
 | 
			
		||||
 | 
			
		||||
            return (flag > 0) ? flag : null;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,6 +29,7 @@ import ch.ethz.seb.sebserver.gbl.util.Result;
 | 
			
		|||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationDAO;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamConfigurationMapDAO;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamDAO;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.exam.ExamAdminService;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.ExamConfigUpdateService;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.ExamSessionService;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -44,19 +45,22 @@ public class ExamConfigUpdateServiceImpl implements ExamConfigUpdateService {
 | 
			
		|||
    private final ExamConfigurationMapDAO examConfigurationMapDAO;
 | 
			
		||||
    private final ExamSessionService examSessionService;
 | 
			
		||||
    private final ExamUpdateHandler examUpdateHandler;
 | 
			
		||||
    private final ExamAdminService examAdminService;
 | 
			
		||||
 | 
			
		||||
    protected ExamConfigUpdateServiceImpl(
 | 
			
		||||
            final ExamDAO examDAO,
 | 
			
		||||
            final ConfigurationDAO configurationDAO,
 | 
			
		||||
            final ExamConfigurationMapDAO examConfigurationMapDAO,
 | 
			
		||||
            final ExamSessionService examSessionService,
 | 
			
		||||
            final ExamUpdateHandler examUpdateHandler) {
 | 
			
		||||
            final ExamUpdateHandler examUpdateHandler,
 | 
			
		||||
            final ExamAdminService examAdminService) {
 | 
			
		||||
 | 
			
		||||
        this.examDAO = examDAO;
 | 
			
		||||
        this.configurationDAO = configurationDAO;
 | 
			
		||||
        this.examConfigurationMapDAO = examConfigurationMapDAO;
 | 
			
		||||
        this.examSessionService = examSessionService;
 | 
			
		||||
        this.examUpdateHandler = examUpdateHandler;
 | 
			
		||||
        this.examAdminService = examAdminService;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // processing:
 | 
			
		||||
| 
						 | 
				
			
			@ -133,6 +137,7 @@ public class ExamConfigUpdateServiceImpl implements ExamConfigUpdateService {
 | 
			
		|||
                            .flatMap(e -> this.examDAO.setSEBRestriction(e.id, true))
 | 
			
		||||
                            .onError(t -> log.error("Failed to update SEB Client restriction for Exam: {}", exam, t));
 | 
			
		||||
                }
 | 
			
		||||
                this.examAdminService.updateAdditionalExamConfigAttributes(exam.id);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // evict each Exam from cache and release the update-lock on DB
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -96,8 +96,8 @@ public class SEBClientVersionServiceImpl implements SEBClientVersionService {
 | 
			
		|||
            final String[] versionNumberSplit = StringUtils.split(versioNumber, Constants.DOT);
 | 
			
		||||
 | 
			
		||||
            final int major = extractVersionNumber(versionNumberSplit[0]);
 | 
			
		||||
            final int minor = extractVersionNumber(versionNumberSplit[1]);
 | 
			
		||||
            final int patch = extractVersionNumber(versionNumberSplit[2]);
 | 
			
		||||
            final int minor = (versionNumberSplit.length > 1) ? extractVersionNumber(versionNumberSplit[1]) : 0;
 | 
			
		||||
            final int patch = (versionNumberSplit.length > 2) ? extractVersionNumber(versionNumberSplit[2]) : 0;
 | 
			
		||||
 | 
			
		||||
            final ClientVersion version = new ClientVersion(osType, major, minor, patch);
 | 
			
		||||
            return allowedSEBVersions
 | 
			
		||||
| 
						 | 
				
			
			@ -106,7 +106,9 @@ public class SEBClientVersionServiceImpl implements SEBClientVersionService {
 | 
			
		|||
                    .findFirst()
 | 
			
		||||
                    .isPresent();
 | 
			
		||||
        } catch (final Exception e) {
 | 
			
		||||
            log.warn("Unexpected error while trying to parse SEB version number in: {} {}", clientOSName,
 | 
			
		||||
            log.warn(
 | 
			
		||||
                    "Invalid SEB version number in: {} {}",
 | 
			
		||||
                    clientOSName,
 | 
			
		||||
                    clientVersion);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -64,13 +64,11 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.Authorization
 | 
			
		|||
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.UserService;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.impl.SEBServerUser;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionService;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.AdditionalAttributesDAO;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamDAO;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserDAO;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.exam.ExamAdminService;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.exam.ExamConfigurationValueService;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.exam.ExamTemplateService;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.institution.SecurityKeyService;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPIService;
 | 
			
		||||
| 
						 | 
				
			
			@ -95,8 +93,6 @@ public class ExamAdministrationController extends EntityController<Exam, Exam> {
 | 
			
		|||
    private final SEBRestrictionService sebRestrictionService;
 | 
			
		||||
    private final SecurityKeyService securityKeyService;
 | 
			
		||||
    private final ExamProctoringRoomService examProctoringRoomService;
 | 
			
		||||
    private final ExamConfigurationValueService examConfigurationValueService;
 | 
			
		||||
    private final AdditionalAttributesDAO additionalAttributesDAO;
 | 
			
		||||
 | 
			
		||||
    public ExamAdministrationController(
 | 
			
		||||
            final AuthorizationService authorization,
 | 
			
		||||
| 
						 | 
				
			
			@ -112,9 +108,7 @@ public class ExamAdministrationController extends EntityController<Exam, Exam> {
 | 
			
		|||
            final ExamSessionService examSessionService,
 | 
			
		||||
            final SEBRestrictionService sebRestrictionService,
 | 
			
		||||
            final SecurityKeyService securityKeyService,
 | 
			
		||||
            final ExamProctoringRoomService examProctoringRoomService,
 | 
			
		||||
            final ExamConfigurationValueService examConfigurationValueService,
 | 
			
		||||
            final AdditionalAttributesDAO additionalAttributesDAO) {
 | 
			
		||||
            final ExamProctoringRoomService examProctoringRoomService) {
 | 
			
		||||
 | 
			
		||||
        super(authorization,
 | 
			
		||||
                bulkActionService,
 | 
			
		||||
| 
						 | 
				
			
			@ -132,8 +126,6 @@ public class ExamAdministrationController extends EntityController<Exam, Exam> {
 | 
			
		|||
        this.sebRestrictionService = sebRestrictionService;
 | 
			
		||||
        this.securityKeyService = securityKeyService;
 | 
			
		||||
        this.examProctoringRoomService = examProctoringRoomService;
 | 
			
		||||
        this.examConfigurationValueService = examConfigurationValueService;
 | 
			
		||||
        this.additionalAttributesDAO = additionalAttributesDAO;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
| 
						 | 
				
			
			@ -607,7 +599,7 @@ public class ExamAdministrationController extends EntityController<Exam, Exam> {
 | 
			
		|||
    @Override
 | 
			
		||||
    protected Result<Exam> notifySaved(final Exam entity) {
 | 
			
		||||
        return Result.tryCatch(() -> {
 | 
			
		||||
            this.saveAdditionalExamConfigAttributes(entity);
 | 
			
		||||
            this.examAdminService.updateAdditionalExamConfigAttributes(entity.id);
 | 
			
		||||
            this.examSessionService.flushCache(entity);
 | 
			
		||||
            return entity;
 | 
			
		||||
        });
 | 
			
		||||
| 
						 | 
				
			
			@ -711,29 +703,6 @@ public class ExamAdministrationController extends EntityController<Exam, Exam> {
 | 
			
		|||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void saveAdditionalExamConfigAttributes(final Exam entity) {
 | 
			
		||||
        try {
 | 
			
		||||
            final String allowedSEBVersion = this.examConfigurationValueService
 | 
			
		||||
                    .getAllowedSEBVersion(entity.id);
 | 
			
		||||
 | 
			
		||||
            if (StringUtils.isNotBlank(allowedSEBVersion)) {
 | 
			
		||||
                this.additionalAttributesDAO.saveAdditionalAttribute(
 | 
			
		||||
                        EntityType.EXAM,
 | 
			
		||||
                        entity.id, Exam.ADDITIONAL_ATTR_ALLOWED_SEB_VERSIONS,
 | 
			
		||||
                        allowedSEBVersion)
 | 
			
		||||
                        .getOrThrow();
 | 
			
		||||
            } else {
 | 
			
		||||
                this.additionalAttributesDAO.delete(
 | 
			
		||||
                        EntityType.EXAM,
 | 
			
		||||
                        entity.id, Exam.ADDITIONAL_ATTR_ALLOWED_SEB_VERSIONS);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } catch (final Exception e) {
 | 
			
		||||
            log.error("Unexpected error while trying to save additional Exam Configuration settings for exam: {}",
 | 
			
		||||
                    entity, e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static Function<Collection<Exam>, List<Exam>> pageSort(final String sort) {
 | 
			
		||||
 | 
			
		||||
        final String sortBy = PageSortOrder.decode(sort);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,6 +47,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationNodeDAO;
 | 
			
		|||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.EntityDAO;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamDAO;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.exam.ExamAdminService;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.ExamConfigUpdateService;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.ExamSessionService;
 | 
			
		||||
import ch.ethz.seb.sebserver.webservice.servicelayer.validation.BeanValidationService;
 | 
			
		||||
| 
						 | 
				
			
			@ -60,6 +61,7 @@ public class ExamConfigurationMappingController extends EntityController<ExamCon
 | 
			
		|||
    private final ConfigurationNodeDAO configurationNodeDAO;
 | 
			
		||||
    private final ExamConfigUpdateService examConfigUpdateService;
 | 
			
		||||
    private final ExamSessionService examSessionService;
 | 
			
		||||
    private final ExamAdminService examAdminService;
 | 
			
		||||
 | 
			
		||||
    protected ExamConfigurationMappingController(
 | 
			
		||||
            final AuthorizationService authorization,
 | 
			
		||||
| 
						 | 
				
			
			@ -71,7 +73,8 @@ public class ExamConfigurationMappingController extends EntityController<ExamCon
 | 
			
		|||
            final ExamDAO examDao,
 | 
			
		||||
            final ConfigurationNodeDAO configurationNodeDAO,
 | 
			
		||||
            final ExamConfigUpdateService examConfigUpdateService,
 | 
			
		||||
            final ExamSessionService examSessionService) {
 | 
			
		||||
            final ExamSessionService examSessionService,
 | 
			
		||||
            final ExamAdminService examAdminService) {
 | 
			
		||||
 | 
			
		||||
        super(
 | 
			
		||||
                authorization,
 | 
			
		||||
| 
						 | 
				
			
			@ -85,6 +88,7 @@ public class ExamConfigurationMappingController extends EntityController<ExamCon
 | 
			
		|||
        this.configurationNodeDAO = configurationNodeDAO;
 | 
			
		||||
        this.examConfigUpdateService = examConfigUpdateService;
 | 
			
		||||
        this.examSessionService = examSessionService;
 | 
			
		||||
        this.examAdminService = examAdminService;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
| 
						 | 
				
			
			@ -181,6 +185,7 @@ public class ExamConfigurationMappingController extends EntityController<ExamCon
 | 
			
		|||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected Result<ExamConfigurationMap> notifyCreated(final ExamConfigurationMap entity) {
 | 
			
		||||
        this.examAdminService.updateAdditionalExamConfigAttributes(entity.examId);
 | 
			
		||||
        // update the attached configurations state to "In Use"
 | 
			
		||||
        return this.configurationNodeDAO.save(new ConfigurationNode(
 | 
			
		||||
                entity.configurationNodeId,
 | 
			
		||||
| 
						 | 
				
			
			@ -200,6 +205,8 @@ public class ExamConfigurationMappingController extends EntityController<ExamCon
 | 
			
		|||
    @Override
 | 
			
		||||
    protected Result<Pair<ExamConfigurationMap, EntityProcessingReport>> notifyDeleted(
 | 
			
		||||
            final Pair<ExamConfigurationMap, EntityProcessingReport> pair) {
 | 
			
		||||
 | 
			
		||||
        this.examAdminService.updateAdditionalExamConfigAttributes(pair.a.examId);
 | 
			
		||||
        // update the attached configurations state to "Ready"
 | 
			
		||||
        return this.configurationNodeDAO.save(new ConfigurationNode(
 | 
			
		||||
                pair.a.configurationNodeId,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2218,6 +2218,7 @@ sebserver.monitoring.exam.connection.status.DISABLED=Canceled
 | 
			
		|||
sebserver.monitoring.exam.connection.status.MISSING_PING=Missing
 | 
			
		||||
sebserver.monitoring.exam.connection.status.MISSING_GRANT=  (No ASK Grant)
 | 
			
		||||
sebserver.monitoring.exam.connection.status.GRANT_DENIED=ASK Grant Denied
 | 
			
		||||
sebserver.monitoring.exam.connection.status.SEB_VERSION_DENIED=SEB Version Invalid 
 | 
			
		||||
 | 
			
		||||
sebserver.monitoring.lock.title=Lock SEB Clients
 | 
			
		||||
sebserver.monitoring.lock.form.info.title=Info
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue