diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/api/APIMessage.java b/src/main/java/ch/ethz/seb/sebserver/gbl/api/APIMessage.java index 1a7dc67d..91a9d4dd 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/api/APIMessage.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/api/APIMessage.java @@ -41,10 +41,11 @@ public class APIMessage implements Serializable { FORBIDDEN("1001", HttpStatus.FORBIDDEN, "FORBIDDEN"), RESOURCE_NOT_FOUND("1002", HttpStatus.NOT_FOUND, "resource not found"), ILLEGAL_API_ARGUMENT("1010", HttpStatus.BAD_REQUEST, "Illegal API request argument"), - UNEXPECTED("1100", HttpStatus.INTERNAL_SERVER_ERROR, "Unexpected intenral server-side error"), + UNEXPECTED("1100", HttpStatus.INTERNAL_SERVER_ERROR, "Unexpected internal server-side error"), FIELD_VALIDATION("1200", HttpStatus.BAD_REQUEST, "Field validation error"), INTEGRITY_VALIDATION("1201", HttpStatus.BAD_REQUEST, "Action would lied to an integrity violation"), PASSWORD_MISMATCH("1300", HttpStatus.BAD_REQUEST, "new password do not match confirmed password"), + MISSING_PASSWORD("1301", HttpStatus.BAD_REQUEST, "Missing Password"), EXAM_CONSISTANCY_VALIDATION_SUPPORTER("1400", HttpStatus.OK, "No Exam Supporter defined for the Exam"), EXAM_CONSISTANCY_VALIDATION_CONFIG("1401", HttpStatus.OK, "No SEB Exam Configuration defined for the Exam"), diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigImport.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigImport.java index 64fbc75a..e30c3778 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigImport.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigImport.java @@ -19,6 +19,7 @@ import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import ch.ethz.seb.sebserver.gbl.api.API; +import ch.ethz.seb.sebserver.gbl.api.APIMessage; import ch.ethz.seb.sebserver.gbl.model.Domain; import ch.ethz.seb.sebserver.gbl.model.EntityKey; import ch.ethz.seb.sebserver.gbl.model.sebconfig.Configuration; @@ -33,17 +34,22 @@ import ch.ethz.seb.sebserver.gui.service.ResourceService; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.page.ModalInputDialogComposer; import ch.ethz.seb.sebserver.gui.service.page.PageContext; +import ch.ethz.seb.sebserver.gui.service.page.PageMessageException; import ch.ethz.seb.sebserver.gui.service.page.PageService; import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent; import ch.ethz.seb.sebserver.gui.service.page.impl.ModalInputDialog; import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCallError; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.ImportExamConfigOnExistingConfig; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.ImportNewExamConfig; import ch.ethz.seb.sebserver.gui.widget.FileUploadSelection; public final class SebExamConfigImport { + private final static PageMessageException MISSING_PASSWORD = new PageMessageException( + new LocTextKey("sebserver.examconfig.action.import.missing-password")); + static Function importFunction( final PageService pageService, final boolean newConfig) { @@ -157,6 +163,19 @@ public final class SebExamConfigImport { } return true; } else { + final Throwable error = configuration.getError(); + if (error instanceof RestCallError) { + ((RestCallError) error) + .getErrorMessages() + .stream() + .filter(APIMessage.ErrorMessage.MISSING_PASSWORD::isOf) + .findFirst() + .ifPresent(message -> formHandle + .getContext() + .publishPageMessage(MISSING_PASSWORD)); + return true; + } + formHandle.getContext().notifyError(configuration.getError()); return true; } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/widget/Message.java b/src/main/java/ch/ethz/seb/sebserver/gui/widget/Message.java index a562b456..f6e8dabb 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/widget/Message.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/widget/Message.java @@ -35,13 +35,18 @@ public final class Message extends MessageBox { super.prepareOpen(); final GridLayout layout = (GridLayout) super.shell.getLayout(); layout.marginTop = 10; - layout.marginBottom = 10; + layout.marginLeft = 10; + layout.marginRight = 10; + layout.verticalSpacing = 10; + layout.horizontalSpacing = 10; super.shell.setData(RWT.CUSTOM_VARIANT, "message"); final Rectangle bounds = super.shell.getBounds(); if (bounds.width < NORMAL_WIDTH) { bounds.x = bounds.x - (NORMAL_WIDTH - bounds.width) / 2; bounds.width = NORMAL_WIDTH; super.shell.setBounds(bounds); + } else { + super.shell.pack(true); } } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/SebConfigEncryptionServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/SebConfigEncryptionServiceImpl.java index 6c554d90..40b2fc7d 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/SebConfigEncryptionServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/SebConfigEncryptionServiceImpl.java @@ -32,6 +32,7 @@ import org.springframework.context.annotation.Lazy; import org.springframework.scheduling.annotation.AsyncResult; import org.springframework.stereotype.Service; +import ch.ethz.seb.sebserver.gbl.api.APIMessage; import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebConfigCryptor; @@ -138,7 +139,8 @@ public final class SebConfigEncryptionServiceImpl implements SebConfigEncryption if ((strategy == Strategy.PASSWORD_PSWD || strategy == Strategy.PASSWORD_PWCC) && StringUtils.isBlank(context.getPassword())) { - return new AsyncResult<>(new IllegalArgumentException("Missing Password")); + return new AsyncResult<>(new APIMessage.APIMessageException( + APIMessage.ErrorMessage.MISSING_PASSWORD.of("Missing Password"))); } // then decrypt stream diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ConfigurationNodeController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ConfigurationNodeController.java index 8ea0b133..3fc92b20 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ConfigurationNodeController.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ConfigurationNodeController.java @@ -22,13 +22,11 @@ import javax.validation.Valid; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.exception.ExceptionUtils; import org.mybatis.dynamic.sql.SqlTable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; @@ -39,7 +37,6 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import ch.ethz.seb.sebserver.gbl.api.API; -import ch.ethz.seb.sebserver.gbl.api.APIMessage; import ch.ethz.seb.sebserver.gbl.api.EntityType; import ch.ethz.seb.sebserver.gbl.api.POSTMapper; import ch.ethz.seb.sebserver.gbl.api.authorization.PrivilegeType; @@ -57,7 +54,6 @@ import ch.ethz.seb.sebserver.gbl.model.sebconfig.TemplateAttribute; import ch.ethz.seb.sebserver.gbl.model.user.UserLogActivityType; import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; import ch.ethz.seb.sebserver.gbl.util.Result; -import ch.ethz.seb.sebserver.gbl.util.Utils; import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ConfigurationNodeRecordDynamicSqlSupport; import ch.ethz.seb.sebserver.webservice.servicelayer.PaginationService; import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.AuthorizationService; @@ -233,7 +229,7 @@ public class ConfigurationNodeController extends EntityController(Arrays.asList(new EntityKey( followup.configurationNodeId, EntityType.CONFIGURATION_NODE)))); - - final Throwable rootCause = ExceptionUtils.getRootCause(doImport.getError()); - return new ResponseEntity<>( - Arrays.asList(APIMessage.ErrorMessage.UNEXPECTED.of(rootCause.getMessage())), - Utils.createJsonContentHeader(), - HttpStatus.BAD_REQUEST); - } else { - return doImport; } + + return doImport + .getOrThrow(); } @RequestMapping( @@ -287,7 +278,7 @@ public class ConfigurationNodeController extends EntityController( - Arrays.asList(APIMessage.ErrorMessage.UNEXPECTED.of(rootCause.getMessage())), - Utils.createJsonContentHeader(), - HttpStatus.BAD_REQUEST); - } else { - return doImport; + } + + return doImport + .getOrThrow(); } @RequestMapping( diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 887d7354..93b816dd 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -463,7 +463,8 @@ sebserver.examconfig.action.import-config=Import Exam Configuration sebserver.examconfig.action.import-file-select=Import From File sebserver.examconfig.action.import-file-password=Password sebserver.examconfig.action.import-config.confirm=Configuration successfully imported -sebserver.examconfig.action.state-change.confirm=This configuration is already attached to an exam.
Please note that changing an attached configuration will take effect on the exam when the configuration changes are saved

Are you sure to change this configuration to an editable state? +sebserver.examconfig.action.import.missing-password=Missing Password: The chosen SEB Configuration is password-protected.

Please choose it again and provide the correct password within the password field. +sebserver.examconfig.action.state-change.confirm=This configuration is already attached to an exam.

Please note that changing an attached configuration will take effect on the exam when the configuration changes are saved

Are you sure to change this configuration to an editable state? sebserver.examconfig.form.title.new=Add Exam Configuration sebserver.examconfig.form.title=Exam Configuration diff --git a/src/main/resources/messages_en.properties b/src/main/resources/messages_en.properties index 2f14f52f..a93c9f10 100644 --- a/src/main/resources/messages_en.properties +++ b/src/main/resources/messages_en.properties @@ -164,7 +164,7 @@ sebserver.lmssetup.list.column.name=Name sebserver.lmssetup.list.column.type=LMS Type sebserver.lmssetup.list.column.active=Active -sebserver.lmssetup.action.list=LMS Setup +sebserver.lmssetup.action.list=LMS Connection Settings sebserver.lmssetup.action.form=LMS Setup sebserver.lmssetup.action.new=Add LMS Setup sebserver.lmssetup.action.list.view=View LMS Setup @@ -210,7 +210,7 @@ sebserver.quizdiscovery.list.column.starttime=Start Time {0} sebserver.quizdiscovery.list.column.endtime=End Time {0} sebserver.quizdiscovery.info.pleaseSelect=Please Select a Quiz first -sebserver.quizdiscovery.action.list=Quiz Discovery +sebserver.quizdiscovery.action.list=LMS Exam Discovery sebserver.quizdiscovery.action.import=Import as Exam sebserver.quizdiscovery.action.details=Show Details @@ -236,7 +236,7 @@ sebserver.exam.list.column.type=Type sebserver.exam.list.empty=No Exam has been found. Please adapt the filter or import one from Quiz -sebserver.exam.action.list=Exam +sebserver.exam.action.list=SEB Exam Settings sebserver.exam.action.list.view=View Exam sebserver.exam.action.list.modify=Edit Exam sebserver.exam.action.modify=Edit Exam diff --git a/src/main/resources/static/css/sebserver.css b/src/main/resources/static/css/sebserver.css index 5d14bfa6..41358a83 100644 --- a/src/main/resources/static/css/sebserver.css +++ b/src/main/resources/static/css/sebserver.css @@ -378,14 +378,14 @@ DateTime-DropDownButton { /* Message titlebar */ Shell.message { + font: 12px Arial, Helvetica, sans-serif; animation: none; border: 1px solid #bdbdbd; background-color: #ffffff; background-image: none; - padding: 0px; opacity: 1; box-shadow: none; - width: 400px; + padding: 5px 10px 5px 10px; } Shell-Titlebar.message {