SEBSERV-335 fixed corner cases

This commit is contained in:
anhefti 2022-12-05 17:04:23 +01:00
parent 5faed87288
commit 4a8a2adc8f
18 changed files with 262 additions and 104 deletions

View file

@ -13,8 +13,6 @@ import java.util.EnumSet;
import java.util.List;
import java.util.function.Predicate;
import org.apache.commons.lang3.BooleanUtils;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@ -327,11 +325,6 @@ public final class ClientConnection implements GrantEntity {
return this.securityCheckGranted;
}
@JsonIgnore
public boolean isSecurityCheckGranted() {
return BooleanUtils.isTrue(this.securityCheckGranted);
}
@Override
public int hashCode() {
final int prime = 31;

View file

@ -25,7 +25,7 @@ public class ClientMonitoringData implements ClientMonitoringDataView {
public final ConnectionStatus status;
public final Map<Long, String> indicatorVals;
public final boolean missingPing;
public final boolean missingGrant;
public final Boolean grantDenied;
public final boolean pendingNotification;
@JsonCreator
@ -34,14 +34,14 @@ public class ClientMonitoringData implements ClientMonitoringDataView {
@JsonProperty(ATTR_STATUS) final ConnectionStatus status,
@JsonProperty(ATTR_INDICATOR_VALUES) final Map<Long, String> indicatorVals,
@JsonProperty(ATTR_MISSING_PING) final boolean missingPing,
@JsonProperty(ATTR_MISSING_GRANT) final boolean missingGrant,
@JsonProperty(ATTR_GRANT_DENIED) final Boolean grantDenied,
@JsonProperty(ATTR_PENDING_NOTIFICATION) final boolean pendingNotification) {
this.id = id;
this.status = status;
this.indicatorVals = indicatorVals;
this.missingPing = missingPing;
this.missingGrant = missingGrant;
this.grantDenied = grantDenied;
this.pendingNotification = pendingNotification;
}
@ -66,9 +66,8 @@ public class ClientMonitoringData implements ClientMonitoringDataView {
}
@Override
public boolean isMissingGrant() {
// TODO Auto-generated method stub
return false;
public Boolean isGrantDenied() {
return this.grantDenied;
}
@Override
@ -76,6 +75,12 @@ public class ClientMonitoringData implements ClientMonitoringDataView {
return this.pendingNotification;
}
public boolean hasChanged(final ClientMonitoringData other) {
return this.status != other.status ||
this.missingPing != other.missingPing ||
!Objects.equals(this.grantDenied, other.grantDenied);
}
public boolean indicatorValuesEquals(final ClientMonitoringData other) {
return Objects.equals(this.indicatorVals, other.indicatorVals);
}

View file

@ -27,7 +27,7 @@ public interface ClientMonitoringDataView {
public static final String ATTR_INDICATOR_VALUES = "iv";
public static final String ATTR_CLIENT_GROUPS = "cg";
public static final String ATTR_MISSING_PING = "mp";
public static final String ATTR_MISSING_GRANT = "mg";
public static final String ATTR_GRANT_DENIED = "gd";
public static final String ATTR_PENDING_NOTIFICATION = "pn";
@JsonProperty(Domain.CLIENT_CONNECTION.ATTR_ID)
@ -42,8 +42,8 @@ public interface ClientMonitoringDataView {
@JsonProperty(ATTR_MISSING_PING)
boolean isMissingPing();
@JsonProperty(ATTR_MISSING_GRANT)
boolean isMissingGrant();
@JsonProperty(ATTR_GRANT_DENIED)
Boolean isGrantDenied();
@JsonProperty(ATTR_PENDING_NOTIFICATION)
boolean isPendingNotification();

View file

@ -22,7 +22,7 @@ import ch.ethz.seb.sebserver.gbl.model.Domain;
public class ClientStaticData {
public static final ClientStaticData NULL_DATA =
new ClientStaticData(-1L, null, null, false, null, Collections.emptySet());
new ClientStaticData(-1L, null, null, null, null, Collections.emptySet());
@JsonProperty(Domain.CLIENT_CONNECTION.ATTR_ID)
public final Long id;
@ -33,8 +33,8 @@ public class ClientStaticData {
@JsonProperty(Domain.CLIENT_CONNECTION.ATTR_EXAM_USER_SESSION_ID)
public final String userSessionId;
@JsonProperty(Domain.CLIENT_CONNECTION.ATTR_SECURITY_CHECK_GRANTED)
public final boolean securityGrant;
@JsonProperty(Domain.CLIENT_CONNECTION.ATTR_ASK)
public final String ask;
@JsonProperty(ClientConnection.ATTR_INFO)
public final String info;
@ -47,14 +47,14 @@ public class ClientStaticData {
@JsonProperty(Domain.CLIENT_CONNECTION.ATTR_ID) final Long id,
@JsonProperty(Domain.CLIENT_CONNECTION.ATTR_CONNECTION_TOKEN) final String connectionToken,
@JsonProperty(Domain.CLIENT_CONNECTION.ATTR_EXAM_USER_SESSION_ID) final String userSessionId,
@JsonProperty(Domain.CLIENT_CONNECTION.ATTR_SECURITY_CHECK_GRANTED) final boolean securityGrant,
@JsonProperty(Domain.CLIENT_CONNECTION.ATTR_ASK) final String ask,
@JsonProperty(ClientConnection.ATTR_INFO) final String info,
@JsonProperty(ClientConnectionData.ATTR_CLIENT_GROUPS) final Set<Long> groups) {
this.id = id;
this.connectionToken = connectionToken;
this.userSessionId = userSessionId;
this.securityGrant = securityGrant;
this.ask = ask;
this.info = info;
this.groups = groups;
}
@ -71,8 +71,8 @@ public class ClientStaticData {
return this.userSessionId;
}
public boolean isSecurityGrant() {
return this.securityGrant;
public String getAsk() {
return this.ask;
}
public String getInfo() {

View file

@ -835,6 +835,13 @@ public final class Utils {
return BooleanUtils.toIntegerObject(b, 1, 0, 0).byteValue();
}
public static Boolean fromByteOrNull(final Byte b) {
if (b == null) {
return null;
}
return BooleanUtils.toBooleanObject(b);
}
public static Boolean fromByte(final Byte b) {
return BooleanUtils.toBooleanObject((b == null) ? 0 : b);
}

View file

@ -410,7 +410,7 @@ public class MonitoringClientConnection implements TemplateComposer {
.call()
.getOrThrow();
if (securityKey.id == null || securityKey.id < 0) {
if (securityKey.key != null && (securityKey.id == null || securityKey.id < 0)) {
actionBuilder
.newAction(ActionDefinition.MONITOR_EXAM_CLIENT_CONNECTION_GRANT_SIGNATURE_KEY)
.withParentEntityKey(parentEntityKey)

View file

@ -98,6 +98,7 @@ public class ResourceService {
private static final Logger log = LoggerFactory.getLogger(ResourceService.class);
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";
public static final Comparator<Tuple<String>> RESOURCE_COMPARATOR = Comparator.comparing(t -> t._2);
@ -625,46 +626,16 @@ public class ResourceService {
.getText(ResourceService.EXAMCONFIG_STATUS_PREFIX + config.configStatus.name());
}
// public Function<ClientConnectionData, String> localizedClientConnectionStatusNameFunction() {
//
// // Memoizing
// final String missing = this.i18nSupport.getText(
// SEB_CONNECTION_STATUS_KEY_PREFIX + MISSING_CLIENT_PING_NAME_KEY,
// MISSING_CLIENT_PING_NAME_KEY);
// final String missingGrant = 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())));
//
// return connectionData -> {
// if (connectionData == null) {
// localizedNames.get(ConnectionStatus.UNDEFINED);
// }
// if (connectionData.clientConnection.status.establishedStatus) {
// if (connectionData.c !connectionData.clientConnection.securityCheckGranted) {
// return missingGrant;
// }
// if (connectionData.missingPing) {
// return missing;
// }
// }
// if (connectionData.missingPing && connectionData.clientConnection.status.establishedStatus) {
// return missing;
// } else {
// return localizedNames.get(connectionData.clientConnection.status);
// }
// };
// }
public Function<MonitoringEntry, String> localizedClientMonitoringStatusNameFunction() {
// Memoizing
final String missingPing = this.i18nSupport.getText(
SEB_CONNECTION_STATUS_KEY_PREFIX + MISSING_CLIENT_PING_NAME_KEY,
MISSING_CLIENT_PING_NAME_KEY);
final String missingGrant = this.i18nSupport.getText(
final String grantDeniedText = this.i18nSupport.getText(
SEB_CONNECTION_STATUS_KEY_PREFIX + DENIED_CLIENT_SEC_GRANT_NAME_KEY,
DENIED_CLIENT_SEC_GRANT_NAME_KEY);
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);
@ -674,12 +645,18 @@ public class ResourceService {
return monitoringEntry -> {
final ConnectionStatus status = monitoringEntry.getStatus();
if (status.establishedStatus) {
if (monitoringEntry.hasMissingGrant()) {
return missingGrant;
}
if (monitoringEntry.hasMissingPing()) {
return missingPing;
}
final Boolean grantDenied = monitoringEntry.grantDenied();
if (grantDenied != null) {
if (grantDenied) {
return grantDeniedText;
}
} else if (monitoringEntry.showNoGrantCheckApplied()) {
return localizedNames.get(status) + grantMissingText;
}
}
return localizedNames.get(status);

View file

@ -77,6 +77,7 @@ public class ClientConnectionDetails implements MonitoringEntry {
public final boolean checkSecurityGrant;
private ClientConnectionData connectionData = null;
public Boolean grantDenied = null;
private boolean statusChanged = true;
private boolean missingChanged = true;
private long startTime = -1;
@ -98,6 +99,7 @@ public class ClientConnectionDetails implements MonitoringEntry {
this.colorData = new ColorData(display);
this.checkSecurityGrant = BooleanUtils.toBoolean(
exam.additionalAttributes.get(Exam.ADDITIONAL_ATTR_SIGNATURE_KEY_CHECK_ENABLED));
this.indicatorMapping = IndicatorData.createFormIndicators(
indicators,
display,
@ -167,9 +169,13 @@ public class ClientConnectionDetails implements MonitoringEntry {
}
@Override
public boolean hasMissingGrant() {
return (this.connectionData != null)
? this.checkSecurityGrant && !this.connectionData.clientConnection.securityCheckGranted : false;
public Boolean grantDenied() {
return this.grantDenied;
}
@Override
public boolean showNoGrantCheckApplied() {
return this.checkSecurityGrant;
}
public void setStatusChangeListener(final Consumer<ClientConnectionData> statusChangeListener) {
@ -194,6 +200,11 @@ public class ClientConnectionDetails implements MonitoringEntry {
.toBoolean(connectionData.missingPing);
}
this.connectionData = connectionData;
if (this.connectionData == null || this.connectionData.clientConnection.securityCheckGranted == null) {
this.grantDenied = null;
} else {
this.grantDenied = !this.connectionData.clientConnection.securityCheckGranted;
}
if (this.startTime < 0) {
this.startTime = System.currentTimeMillis();
}
@ -230,11 +241,13 @@ public class ClientConnectionDetails implements MonitoringEntry {
getGroupInfo());
}
if (this.missingChanged) {
if (this.missingChanged || this.statusChanged) {
// update status
form.setFieldValue(
Domain.CLIENT_CONNECTION.ATTR_STATUS,
this.localizedClientConnectionStatusNameFunction.apply(this));
String stateName = this.localizedClientConnectionStatusNameFunction.apply(this);
if (stateName != null) {
stateName = stateName.replace("&nbsp;", " ");
}
form.setFieldValue(Domain.CLIENT_CONNECTION.ATTR_STATUS, stateName);
final Color statusColor = this.colorData.getStatusColor(this);
final Color statusTextColor = this.colorData.getStatusTextColor(statusColor);
form.setFieldColor(Domain.CLIENT_CONNECTION.ATTR_STATUS, statusColor);

View file

@ -479,9 +479,13 @@ public final class ClientConnectionTable implements FullPageMonitoringGUIUpdate
}
@Override
public boolean hasMissingGrant() {
return (this.staticData != null)
? ClientConnectionTable.this.checkSecurityGrant && !this.staticData.securityGrant : false;
public Boolean grantDenied() {
return this.monitoringData.grantDenied;
}
@Override
public boolean showNoGrantCheckApplied() {
return ClientConnectionTable.this.checkSecurityGrant;
}
private void update(final TableItem tableItem, final boolean force) {
@ -670,10 +674,7 @@ public final class ClientConnectionTable implements FullPageMonitoringGUIUpdate
}
boolean push(final ClientMonitoringData monitoringData) {
this.dataChanged = this.monitoringData == null ||
this.monitoringData.status != monitoringData.status ||
this.monitoringData.missingPing != monitoringData.missingPing ||
this.monitoringData.missingGrant != monitoringData.missingGrant;
this.dataChanged = this.monitoringData == null || this.monitoringData.hasChanged(monitoringData);
this.indicatorValueChanged = this.monitoringData == null ||
(this.monitoringData.status.clientActiveStatus
&& !this.monitoringData.indicatorValuesEquals(monitoringData));
@ -739,7 +740,6 @@ public final class ClientConnectionTable implements FullPageMonitoringGUIUpdate
private ClientConnectionTable getOuterType() {
return ClientConnectionTable.this;
}
}
private void fetchStaticClientConnectionData() {

View file

@ -41,13 +41,12 @@ public class ColorData {
return this.defaultColor;
}
final Boolean grantDenied = entry.grantDenied();
switch (status) {
case ACTIVE:
return (entry.hasMissingGrant())
? this.color3
: (entry.hasMissingPing())
? this.color2
: this.color1;
return (grantDenied != null && grantDenied)
? this.color3 : (entry.hasMissingPing())
? this.color2 : this.color1;
default:
return this.defaultColor;
}
@ -67,8 +66,9 @@ public class ColorData {
case AUTHENTICATED:
return 1;
case ACTIVE:
return (connectionData.clientConnection.securityCheckGranted) ? -1
: (connectionData.missingPing) ? 0 : 2;
return (connectionData.clientConnection.securityCheckGranted)
? -1 : (connectionData.missingPing)
? 0 : 2;
case CLOSED:
return 3;
default:
@ -81,12 +81,16 @@ public class ColorData {
return 100;
}
final Boolean grantDenied = entry.grantDenied();
switch (entry.getStatus()) {
case CONNECTION_REQUESTED:
case AUTHENTICATED:
return 1;
case ACTIVE:
return (entry.hasMissingGrant()) ? -1 : (entry.hasMissingPing()) ? 0 : 2;
return (grantDenied == null)
? -1 : (grantDenied)
? -2 : (entry.hasMissingPing())
? 0 : 2;
case CLOSED:
return 4;
default:

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2022 ETH Zürich, Educational Development and Technology (LET)
*
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
@ -11,10 +11,19 @@ package ch.ethz.seb.sebserver.gui.service.session;
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection.ConnectionStatus;
public interface MonitoringEntry {
ConnectionStatus getStatus();
boolean hasMissingPing();
boolean hasMissingGrant();
/** Indicates the security key grant check state
* true = grant denied
* false = granted
* null = not checked yet
*
* @return the security key grant check state */
Boolean grantDenied();
boolean showNoGrantCheckApplied();
}

View file

@ -0,0 +1,128 @@
/*
* Copyright (c) 2022 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package ch.ethz.seb.sebserver.webservice.datalayer.checks;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
import ch.ethz.seb.sebserver.gbl.util.Result;
import ch.ethz.seb.sebserver.webservice.DBIntegrityCheck;
@Lazy
@Component
@WebServiceProfile
public class TableCharsetCheck implements DBIntegrityCheck {
private static final String UTF8MB4_GENERAL_CI = "utf8mb4_general_ci";
private static final Logger log = LoggerFactory.getLogger(TableCharsetCheck.class);
private final DataSource dataSource;
private final String schemaName;
public TableCharsetCheck(
final DataSource dataSource,
final Environment environment) {
super();
this.dataSource = dataSource;
this.schemaName = environment.getProperty("sebserver.init.database.integrity.check.schema", (String) null);
}
@Override
public String name() {
return "TableCharsetCheck";
}
@Override
public String description() {
return "Checks the char-set and collation of DB tables if correct utf8mb4_general_ci is set";
}
@Override
public Result<String> applyCheck(final boolean tryFix) {
if (StringUtils.isEmpty(this.schemaName)) {
return Result.of("Skip check since sebserver.init.database.integrity.check.schema is not defined");
}
Connection connection = null;
try {
connection = this.dataSource.getConnection();
final PreparedStatement prepareStatement =
connection.prepareStatement(
"SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = \"" + this.schemaName + "\"");
prepareStatement.execute();
final ResultSet resultSet = prepareStatement.getResultSet();
final Map<String, String> tablesWithWrongCollation = new HashMap<>();
while (resultSet.next()) {
final String collation = resultSet.getString("TABLE_COLLATION");
if (!UTF8MB4_GENERAL_CI.equals(collation)) {
tablesWithWrongCollation.put(resultSet.getString("TABLE_NAME"), collation);
}
}
final Connection con = connection;
if (!tablesWithWrongCollation.isEmpty()) {
if (tryFix) {
tablesWithWrongCollation.entrySet().forEach(entry -> tryFix(con, entry));
} else {
return Result.of("Found tables with wrong collation: " + tablesWithWrongCollation);
}
}
} catch (final Exception e) {
log.error("Failed to apply database table check: ", e);
} finally {
if (connection != null) {
try {
connection.close();
} catch (final SQLException e) {
log.error("Failed to close connection: ", e);
}
}
}
return Result.of("OK");
}
private void tryFix(final Connection connection, final Map.Entry<String, String> entry) {
try {
log.info("Try to fix collation for table: {}", entry);
final PreparedStatement prepareStatement = connection.prepareStatement(
"ALTER TABLE " + entry.getKey() + " CONVERT TO CHARACTER SET 'utf8mb4' COLLATE '"
+ UTF8MB4_GENERAL_CI
+ "'");
prepareStatement.execute();
log.info("Successfully changed collision for table: {}", entry.getKey());
} catch (final Exception e) {
log.error("Failed to changed collision for table", e);
}
}
}

View file

@ -791,7 +791,10 @@ public class ClientConnectionDAOImpl implements ClientConnectionDAO {
SqlBuilder.isIn(ClientConnection.SECURE_CHECK_STATES))
.and(
ClientConnectionRecordDynamicSqlSupport.securityCheckGranted,
SqlBuilder.isEqualTo(Constants.BYTE_FALSE))
SqlBuilder.isEqualTo(Constants.BYTE_FALSE), SqlBuilder.or(
ClientConnectionRecordDynamicSqlSupport.securityCheckGranted,
SqlBuilder.isNull()))
.and(ClientConnectionRecordDynamicSqlSupport.ask, SqlBuilder.isNotNull())
.build()
.execute());
}
@ -864,7 +867,7 @@ public class ClientConnectionDAOImpl implements ClientConnectionDAO {
record.getUpdateTime(),
record.getRemoteProctoringRoomId(),
BooleanUtils.toBooleanObject(record.getRemoteProctoringRoomUpdate()),
Utils.fromByte(record.getSecurityCheckGranted()),
Utils.fromByteOrNull(record.getSecurityCheckGranted()),
record.getAsk());
});
}

View file

@ -22,6 +22,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import ch.ethz.seb.sebserver.gbl.Constants;
import ch.ethz.seb.sebserver.gbl.api.APIMessage.FieldValidationException;
import ch.ethz.seb.sebserver.gbl.api.EntityType;
import ch.ethz.seb.sebserver.gbl.model.Domain;
@ -181,7 +182,8 @@ public class SecurityKeyServiceImpl implements SecurityKeyService {
@Override
public void updateAppSignatureKeyGrant(final ClientConnectionRecord record) {
try {
if (!Utils.fromByte(record.getSecurityCheckGranted())) {
final Byte securityCheckGranted = record.getSecurityCheckGranted();
if (securityCheckGranted == null || securityCheckGranted == Constants.BYTE_FALSE) {
final String token = record.getConnectionToken();
if (applyAppSignatureCheck(
record.getInstitutionId(),
@ -195,14 +197,9 @@ public class SecurityKeyServiceImpl implements SecurityKeyService {
log.debug("Update app-signature-key grant for client connection: {}", token);
}
this.clientConnectionDAO
.save(new ClientConnection(
record.getId(), null,
null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, true, null))
.onError(error -> log.error("Failed to save ClientConnection grant: ",
error))
.onSuccess(c -> this.examSessionCacheService.evictClientConnection(token));
saveSecurityCheckState(record, true);
} else if (securityCheckGranted == null) {
saveSecurityCheckState(record, false);
}
}
} catch (final Exception e) {
@ -365,4 +362,15 @@ public class SecurityKeyServiceImpl implements SecurityKeyService {
return m;
}
private void saveSecurityCheckState(final ClientConnectionRecord record, final Boolean checkStatus) {
this.clientConnectionDAO
.save(new ClientConnection(
record.getId(), null,
null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, checkStatus, null))
.onError(error -> log.error("Failed to save ClientConnection grant: ",
error))
.onSuccess(c -> this.examSessionCacheService.evictClientConnection(record.getConnectionToken()));
}
}

View file

@ -44,6 +44,8 @@ public class ClientConnectionDataInternal extends ClientConnectionData {
PingIntervalClientIndicator pingIndicator = null;
private final PendingNotificationIndication pendingNotificationIndication;
private final Boolean grantDenied;
protected ClientConnectionDataInternal(
final ClientConnection clientConnection,
final PendingNotificationIndication pendingNotificationIndication,
@ -68,6 +70,12 @@ public class ClientConnectionDataInternal extends ClientConnectionData {
.add(clientIndicator);
}
}
if (clientConnection.securityCheckGranted == null) {
this.grantDenied = null;
} else {
this.grantDenied = !clientConnection.securityCheckGranted;
}
}
public final void notifyPing(final long timestamp, final int pingNumber) {
@ -143,9 +151,10 @@ public class ClientConnectionDataInternal extends ClientConnectionData {
}
@Override
public boolean isMissingGrant() {
return BooleanUtils.isFalse(ClientConnectionDataInternal.this.clientConnection.securityCheckGranted);
public Boolean isGrantDenied() {
return ClientConnectionDataInternal.this.grantDenied;
}
};
/** This is a static monitoring connection data wrapper/holder */
@ -155,7 +164,7 @@ public class ClientConnectionDataInternal extends ClientConnectionData {
ClientConnectionDataInternal.this.clientConnection.id,
ClientConnectionDataInternal.this.clientConnection.connectionToken,
ClientConnectionDataInternal.this.clientConnection.userSessionId,
ClientConnectionDataInternal.this.clientConnection.getSecurityCheckGranted(),
ClientConnectionDataInternal.this.clientConnection.ask,
ClientConnectionDataInternal.this.clientConnection.info,
this.groups);

View file

@ -278,7 +278,7 @@ public class SEBClientConnectionServiceImpl implements SEBClientConnectionServic
null,
null,
null,
false,
null,
getSignatureHash(appSignatureKey, connectionToken)))
.getOrThrow();
@ -400,7 +400,7 @@ public class SEBClientConnectionServiceImpl implements SEBClientConnectionServic
null,
null,
proctoringEnabled,
false,
null,
getSignatureHash(appSignatureKey, connectionToken));
// ClientConnection integrity check

View file

@ -9,6 +9,7 @@ sebserver.init.organisation.name=SEB Server
sebserver.init.adminaccount.username=sebserver-admin
sebserver.init.database.integrity.checks=true
sebserver.init.database.integrity.try-fix=true
sebserver.init.database.integrity.check.schema=SEBServer
### webservice caching
spring.cache.jcache.provider=org.ehcache.jsr107.EhcacheCachingProvider

View file

@ -2077,7 +2077,8 @@ sebserver.monitoring.exam.connection.status.CLOSED=Closed
sebserver.monitoring.exam.connection.status.ABORTED=Aborted
sebserver.monitoring.exam.connection.status.DISABLED=Canceled
sebserver.monitoring.exam.connection.status.MISSING_PING=Missing
sebserver.monitoring.exam.connection.status.MISSING_GRANT=Not Granted (ASK)
sebserver.monitoring.exam.connection.status.MISSING_GRANT=&nbsp;&nbsp;(No ASK Grant)
sebserver.monitoring.exam.connection.status.GRANT_DENIED=ASK Grant Denied
sebserver.monitoring.lock.title=Lock SEB Clients
sebserver.monitoring.lock.form.info.title=Info