SEBSERV-135 improved identity handling and error messages
This commit is contained in:
parent
730ec7dfc8
commit
d76f1f5ca9
16 changed files with 77 additions and 52 deletions
|
@ -203,7 +203,7 @@ public class APIMessage implements Serializable {
|
|||
return ErrorMessage.FIELD_VALIDATION.of(fieldName, args);
|
||||
}
|
||||
|
||||
public static String toHTML(final String errorMessage, final List<APIMessage> messages) {
|
||||
public static String toHTML(final String errorMessage, final Collection<APIMessage> messages) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append("<b>Failure:</b>").append("<br/><br/>").append(errorMessage).append("<br/><br/>");
|
||||
builder.append("<b>Detail Messages:</b><br/><br/>");
|
||||
|
@ -220,7 +220,7 @@ public class APIMessage implements Serializable {
|
|||
* within an Exception and throw. The Exception will be caught a the
|
||||
* APIExceptionHandler endpoint. The APIMessage will be extracted
|
||||
* and send as response. */
|
||||
public static class APIMessageException extends RuntimeException {
|
||||
public static class APIMessageException extends RuntimeException implements APIMessageError {
|
||||
|
||||
private static final long serialVersionUID = 1453431210820677296L;
|
||||
|
||||
|
@ -246,6 +246,7 @@ public class APIMessage implements Serializable {
|
|||
this.apiMessages = Arrays.asList(errorMessage.of(detail, attributes));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<APIMessage> getAPIMessages() {
|
||||
return this.apiMessages;
|
||||
}
|
||||
|
@ -283,11 +284,11 @@ public class APIMessage implements Serializable {
|
|||
}
|
||||
|
||||
public static boolean checkError(final Exception error, final ErrorMessage errorMessage) {
|
||||
if (!(error instanceof APIMessageException)) {
|
||||
if (!(error instanceof APIMessageError)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final APIMessageException _error = (APIMessageException) error;
|
||||
final APIMessageError _error = (APIMessageError) error;
|
||||
return _error.getAPIMessages()
|
||||
.stream()
|
||||
.filter(msg -> errorMessage.messageCode.equals(msg.messageCode))
|
||||
|
|
|
@ -8,14 +8,14 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.gbl.api;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Collection;
|
||||
|
||||
/** Defines an API message error holder that supplies a List of APIMessage if error happened */
|
||||
public interface APIMessageError {
|
||||
|
||||
/** Get a List of APIMessage errors if error happened
|
||||
*
|
||||
* @return a List of APIMessage errors if error happened or empty list of not*/
|
||||
List<APIMessage> getErrorMessages();
|
||||
* @return a List of APIMessage errors if error happened or empty list of not */
|
||||
Collection<APIMessage> getAPIMessages();
|
||||
|
||||
}
|
||||
|
|
|
@ -203,10 +203,16 @@ public final class SEBClientConfig implements GrantEntity, Activatable {
|
|||
this.configPurpose = configPurpose;
|
||||
|
||||
this.sebServerPingTime = sebServerPingTime;
|
||||
this.vdiType = vdiType;
|
||||
this.vdiExecutable = vdiExecutable != null ? vdiExecutable : vdiType.defaultExecutable;
|
||||
this.vdiPath = vdiPath != null ? vdiPath : vdiType.defaultPath;
|
||||
this.vdiArguments = vdiArguments != null ? vdiArguments : vdiType.defaultArguments;
|
||||
this.vdiType = vdiType != null ? vdiType : VDIType.NO;
|
||||
this.vdiExecutable = vdiExecutable != null
|
||||
? vdiExecutable
|
||||
: vdiType != null ? vdiType.defaultExecutable : null;
|
||||
this.vdiPath = vdiPath != null
|
||||
? vdiPath
|
||||
: vdiType != null ? vdiType.defaultPath : null;
|
||||
this.vdiArguments = vdiArguments != null
|
||||
? vdiArguments
|
||||
: vdiType != null ? vdiType.defaultArguments : null;
|
||||
|
||||
this.fallback = fallback;
|
||||
this.fallbackStartURL = fallbackStartURL;
|
||||
|
|
|
@ -176,7 +176,7 @@ public class CertificateImportPopup {
|
|||
final Exception error = result.getError();
|
||||
if (error instanceof RestCallError) {
|
||||
((RestCallError) error)
|
||||
.getErrorMessages()
|
||||
.getAPIMessages()
|
||||
.stream()
|
||||
.findFirst()
|
||||
.ifPresent(message -> {
|
||||
|
|
|
@ -75,6 +75,8 @@ public class CertificateList implements TemplateComposer {
|
|||
new LocTextKey("sebserver.certificate.action.import-config.confirm");
|
||||
static final LocTextKey FORM_ACTION_MESSAGE_IN_USE_TEXT_KEY =
|
||||
new LocTextKey("sebserver.certificate.action.remove.in-use");
|
||||
static final LocTextKey FORM_ACTION_MESSAGE_REMOVE_CONFIRM_TEXT_KEY =
|
||||
new LocTextKey("sebserver.certificate.action.remove.confirm");
|
||||
|
||||
private final TableFilterAttribute aliasFilter = new TableFilterAttribute(
|
||||
CriteriaType.TEXT,
|
||||
|
@ -155,6 +157,7 @@ public class CertificateList implements TemplateComposer {
|
|||
.publishIf(() -> grantCheck.iw())
|
||||
|
||||
.newAction(ActionDefinition.SEB_CERTIFICATE_REMOVE)
|
||||
.withConfirm(() -> FORM_ACTION_MESSAGE_REMOVE_CONFIRM_TEXT_KEY)
|
||||
.withSelect(
|
||||
table::getSelection,
|
||||
this::removeCertificate,
|
||||
|
|
|
@ -16,6 +16,7 @@ import org.eclipse.rap.rwt.RWT;
|
|||
import org.eclipse.rap.rwt.client.service.UrlLauncher;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.swt.widgets.Listener;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -332,14 +333,16 @@ public class SEBClientConfigForm implements TemplateComposer {
|
|||
// VDI
|
||||
|
||||
.withDefaultSpanInput(2)
|
||||
.addField(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))
|
||||
.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
|
||||
|
@ -472,10 +475,18 @@ public class SEBClientConfigForm implements TemplateComposer {
|
|||
};
|
||||
|
||||
if (!isReadonly) {
|
||||
formHandleAnchor.formHandle.getForm().getFieldInput(SEBClientConfig.ATTR_FALLBACK)
|
||||
.addListener(SWT.Selection, selectionListener);
|
||||
formHandleAnchor.formHandle.getForm().getFieldInput(SEBClientConfig.ATTR_VDI_TYPE)
|
||||
.addListener(SWT.Selection, selectionListener);
|
||||
final Control fallbackInput = formHandleAnchor.formHandle
|
||||
.getForm()
|
||||
.getFieldInput(SEBClientConfig.ATTR_FALLBACK);
|
||||
if (fallbackInput != null) {
|
||||
fallbackInput.addListener(SWT.Selection, selectionListener);
|
||||
}
|
||||
final Control vdiInput = formHandleAnchor.formHandle
|
||||
.getForm()
|
||||
.getFieldInput(SEBClientConfig.ATTR_VDI_TYPE);
|
||||
if (vdiInput != null) {
|
||||
vdiInput.addListener(SWT.Selection, selectionListener);
|
||||
}
|
||||
}
|
||||
|
||||
formContent.layout();
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
package ch.ethz.seb.sebserver.gui.content;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
@ -210,7 +211,7 @@ public class SEBExamConfigImportPopup {
|
|||
final Exception error = configuration.getError();
|
||||
if (error instanceof RestCallError) {
|
||||
((RestCallError) error)
|
||||
.getErrorMessages()
|
||||
.getAPIMessages()
|
||||
.stream()
|
||||
.findFirst()
|
||||
.ifPresent(message -> {
|
||||
|
@ -393,8 +394,8 @@ public class SEBExamConfigImportPopup {
|
|||
private static void notifyErrorOnSave(final Exception error, final PageContext context) {
|
||||
if (error instanceof APIMessageError) {
|
||||
try {
|
||||
final List<APIMessage> errorMessages = ((APIMessageError) error).getErrorMessages();
|
||||
final APIMessage apiMessage = errorMessages.get(0);
|
||||
final Collection<APIMessage> errorMessages = ((APIMessageError) error).getAPIMessages();
|
||||
final APIMessage apiMessage = errorMessages.iterator().next();
|
||||
if (APIMessage.ErrorMessage.INTEGRITY_VALIDATION.isOf(apiMessage)) {
|
||||
context.publishPageMessage(new PageMessageException(MESSAGE_SAVE_INTEGRITY_VIOLATION));
|
||||
} else {
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
package ch.ethz.seb.sebserver.gui.content;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
|
@ -324,8 +325,8 @@ public class SEBSettingsForm implements TemplateComposer {
|
|||
public void notifyErrorOnSave(final Exception error, final PageContext context) {
|
||||
if (error instanceof APIMessageError) {
|
||||
try {
|
||||
final List<APIMessage> errorMessages = ((APIMessageError) error).getErrorMessages();
|
||||
final APIMessage apiMessage = errorMessages.get(0);
|
||||
final Collection<APIMessage> errorMessages = ((APIMessageError) error).getAPIMessages();
|
||||
final APIMessage apiMessage = errorMessages.iterator().next();
|
||||
if (APIMessage.ErrorMessage.INTEGRITY_VALIDATION.isOf(apiMessage)) {
|
||||
throw new PageMessageException(MESSAGE_SAVE_INTEGRITY_VIOLATION);
|
||||
} else {
|
||||
|
|
|
@ -144,13 +144,13 @@ public class FormHandle<T extends Entity> {
|
|||
if (error instanceof RestCallError) {
|
||||
|
||||
final List<APIMessage> fieldValidationErrors = ((RestCallError) error)
|
||||
.getErrorMessages()
|
||||
.getAPIMessages()
|
||||
.stream()
|
||||
.filter(APIMessage.ErrorMessage.FIELD_VALIDATION::isOf)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
final List<APIMessage> noneFieldValidationErrors = ((RestCallError) error)
|
||||
.getErrorMessages()
|
||||
.getAPIMessages()
|
||||
.stream()
|
||||
.filter(message -> !APIMessage.ErrorMessage.FIELD_VALIDATION.isOf(message))
|
||||
.collect(Collectors.toList());
|
||||
|
|
|
@ -390,7 +390,7 @@ public class ExamConfigurationServiceImpl implements ExamConfigurationService {
|
|||
|
||||
private String verifyErrorMessage(final Exception error) {
|
||||
if (error instanceof RestCallError) {
|
||||
final List<APIMessage> errorMessages = ((RestCallError) error).getErrorMessages();
|
||||
final List<APIMessage> errorMessages = ((RestCallError) error).getAPIMessages();
|
||||
if (errorMessages.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
package ch.ethz.seb.sebserver.gui.service.page.impl;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -332,7 +333,7 @@ public class PageContextImpl implements PageContext {
|
|||
: error.getMessage();
|
||||
|
||||
if (error instanceof APIMessageError) {
|
||||
final List<APIMessage> errorMessages = ((APIMessageError) error).getErrorMessages();
|
||||
final Collection<APIMessage> errorMessages = ((APIMessageError) error).getAPIMessages();
|
||||
final MessageBox messageBox = new Message(
|
||||
getShell(),
|
||||
this.i18nSupport.getText("sebserver.error.unexpected"),
|
||||
|
|
|
@ -38,7 +38,7 @@ public class RestCallError extends RuntimeException implements APIMessageError {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<APIMessage> getErrorMessages() {
|
||||
public List<APIMessage> getAPIMessages() {
|
||||
return this.errors;
|
||||
}
|
||||
|
||||
|
|
|
@ -223,12 +223,7 @@ public class CertificateDAOImpl implements CertificateDAO {
|
|||
|
||||
// dataEncipherment
|
||||
if (keyUsage[2] || keyUsage[3]) {
|
||||
final String alias = certificates.keyStore.engineGetCertificateAlias(cert);
|
||||
if (this.cryptor.getPrivateKey(certificates.keyStore, alias).hasValue()) {
|
||||
result.add(CertificateType.DATA_ENCIPHERMENT_PRIVATE_KEY);
|
||||
} else {
|
||||
result.add(CertificateType.DATA_ENCIPHERMENT);
|
||||
}
|
||||
result.add(CertificateType.DATA_ENCIPHERMENT);
|
||||
}
|
||||
|
||||
// keyCertSign
|
||||
|
@ -240,6 +235,11 @@ public class CertificateDAOImpl implements CertificateDAO {
|
|||
result.add(CertificateType.UNKNOWN);
|
||||
}
|
||||
|
||||
final String alias = certificates.keyStore.engineGetCertificateAlias(cert);
|
||||
if (this.cryptor.getPrivateKey(certificates.keyStore, alias).hasValue()) {
|
||||
result.add(CertificateType.DATA_ENCIPHERMENT_PRIVATE_KEY);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ public abstract class AbstractCertificateCryptor {
|
|||
|
||||
final String algorithm = cert.getPublicKey().getAlgorithm();
|
||||
final Cipher encryptCipher = Cipher.getInstance(algorithm);
|
||||
encryptCipher.init(Cipher.ENCRYPT_MODE, cert);
|
||||
encryptCipher.init(Cipher.ENCRYPT_MODE, cert.getPublicKey());
|
||||
return encryptCipher.doFinal(data, 0, length);
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,7 @@ public abstract class AbstractCertificateCryptor {
|
|||
|
||||
final String algorithm = cert.getPublicKey().getAlgorithm();
|
||||
final Cipher encryptCipher = Cipher.getInstance(algorithm);
|
||||
encryptCipher.init(Cipher.DECRYPT_MODE, cert);
|
||||
encryptCipher.init(Cipher.DECRYPT_MODE, cert.getPublicKey());
|
||||
return encryptCipher.doFinal(encryptedData, 0, length);
|
||||
}
|
||||
|
||||
|
|
|
@ -1607,6 +1607,7 @@ sebserver.certificate.action.import.missing-password=The certificate file needs
|
|||
sebserver.certificate.action.import-config.confirm=Certificate(s) successfully imported
|
||||
sebserver.certificate.message.error.file=Unsupported file type
|
||||
sebserver.certificate.action.import-file-select.no=Please select a valid file
|
||||
sebserver.certificate.action.remove.confirm=Are you sure you want delete the selected Certificate(s)?
|
||||
sebserver.certificate.action.remove.in-use=This certificate is in use and cannot be removed.
|
||||
|
||||
|
||||
|
|
|
@ -381,7 +381,7 @@ public class UseCasesIntegrationTest extends GuiIntegrationTest {
|
|||
RestCallError error = (RestCallError) call.getError();
|
||||
assertEquals(
|
||||
"[APIMessage [messageCode=1001, systemMessage=FORBIDDEN, details=No edit right grant for user: TestInstAdmin, attributes=[]]]",
|
||||
String.valueOf(error.getErrorMessages()));
|
||||
String.valueOf(error.getAPIMessages()));
|
||||
|
||||
// change password
|
||||
final Result<UserInfo> passwordChange = restService
|
||||
|
@ -400,7 +400,7 @@ public class UseCasesIntegrationTest extends GuiIntegrationTest {
|
|||
error = (RestCallError) instNames.getError();
|
||||
assertEquals(
|
||||
"UNAUTHORIZED",
|
||||
String.valueOf(error.getErrorMessages().get(0).getSystemMessage()));
|
||||
String.valueOf(error.getAPIMessages().get(0).getSystemMessage()));
|
||||
|
||||
// login again with the new password and check roles
|
||||
restService = createRestServiceForUser(
|
||||
|
@ -2339,7 +2339,7 @@ public class UseCasesIntegrationTest extends GuiIntegrationTest {
|
|||
.getOrThrow();
|
||||
fail("Forbidden error message expected here");
|
||||
} catch (final RestCallError e) {
|
||||
final APIMessage apiMessage = e.getErrorMessages().get(0);
|
||||
final APIMessage apiMessage = e.getAPIMessages().get(0);
|
||||
assertEquals("1001", apiMessage.messageCode);
|
||||
assertEquals("FORBIDDEN", apiMessage.systemMessage);
|
||||
}
|
||||
|
@ -2395,7 +2395,7 @@ public class UseCasesIntegrationTest extends GuiIntegrationTest {
|
|||
.getOrThrow();
|
||||
fail("no resource found exception expected here");
|
||||
} catch (final RestCallError e) {
|
||||
final APIMessage apiMessage = e.getErrorMessages().get(0);
|
||||
final APIMessage apiMessage = e.getAPIMessages().get(0);
|
||||
assertEquals("1002", apiMessage.getMessageCode());
|
||||
assertEquals("resource not found", apiMessage.getSystemMessage());
|
||||
}
|
||||
|
@ -2408,7 +2408,7 @@ public class UseCasesIntegrationTest extends GuiIntegrationTest {
|
|||
.getOrThrow();
|
||||
fail("no resource found exception expected here");
|
||||
} catch (final RestCallError e) {
|
||||
final APIMessage apiMessage = e.getErrorMessages().get(0);
|
||||
final APIMessage apiMessage = e.getAPIMessages().get(0);
|
||||
assertEquals("1002", apiMessage.getMessageCode());
|
||||
assertEquals("resource not found", apiMessage.getSystemMessage());
|
||||
}
|
||||
|
@ -2419,7 +2419,7 @@ public class UseCasesIntegrationTest extends GuiIntegrationTest {
|
|||
.getOrThrow();
|
||||
fail("no resource found exception expected here");
|
||||
} catch (final RestCallError e) {
|
||||
final APIMessage apiMessage = e.getErrorMessages().get(0);
|
||||
final APIMessage apiMessage = e.getAPIMessages().get(0);
|
||||
assertEquals("1002", apiMessage.getMessageCode());
|
||||
assertEquals("resource not found", apiMessage.getSystemMessage());
|
||||
}
|
||||
|
@ -2430,7 +2430,7 @@ public class UseCasesIntegrationTest extends GuiIntegrationTest {
|
|||
.getOrThrow();
|
||||
fail("no resource found exception expected here");
|
||||
} catch (final RestCallError e) {
|
||||
final APIMessage apiMessage = e.getErrorMessages().get(0);
|
||||
final APIMessage apiMessage = e.getAPIMessages().get(0);
|
||||
assertEquals("1002", apiMessage.getMessageCode());
|
||||
assertEquals("resource not found", apiMessage.getSystemMessage());
|
||||
}
|
||||
|
@ -2441,7 +2441,7 @@ public class UseCasesIntegrationTest extends GuiIntegrationTest {
|
|||
.getOrThrow();
|
||||
fail("no resource found exception expected here");
|
||||
} catch (final RestCallError e) {
|
||||
final APIMessage apiMessage = e.getErrorMessages().get(0);
|
||||
final APIMessage apiMessage = e.getAPIMessages().get(0);
|
||||
assertEquals("1002", apiMessage.getMessageCode());
|
||||
assertEquals("resource not found", apiMessage.getSystemMessage());
|
||||
}
|
||||
|
@ -2452,7 +2452,7 @@ public class UseCasesIntegrationTest extends GuiIntegrationTest {
|
|||
.getOrThrow();
|
||||
fail("no resource found exception expected here");
|
||||
} catch (final RestCallError e) {
|
||||
final APIMessage apiMessage = e.getErrorMessages().get(0);
|
||||
final APIMessage apiMessage = e.getAPIMessages().get(0);
|
||||
assertEquals("1002", apiMessage.getMessageCode());
|
||||
assertEquals("resource not found", apiMessage.getSystemMessage());
|
||||
}
|
||||
|
@ -2463,7 +2463,7 @@ public class UseCasesIntegrationTest extends GuiIntegrationTest {
|
|||
.getOrThrow();
|
||||
fail("no resource found exception expected here");
|
||||
} catch (final RestCallError e) {
|
||||
final APIMessage apiMessage = e.getErrorMessages().get(0);
|
||||
final APIMessage apiMessage = e.getAPIMessages().get(0);
|
||||
assertEquals("1002", apiMessage.getMessageCode());
|
||||
assertEquals("resource not found", apiMessage.getSystemMessage());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue