findbug fixes and bugfixes in import

This commit is contained in:
anhefti 2019-11-25 15:15:00 +01:00
parent 31f8dc295b
commit 5a6527961a
35 changed files with 168 additions and 115 deletions

View file

@ -19,16 +19,12 @@
<Package name="ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation" />
<Bug pattern="NM_CONFUSING" />
</Match>
<Match>
<Package name="ch.ethz.seb.sebserver" />
<Bug pattern="REC_CATCH_EXCEPTION" />
</Match>
<Match>
<Package name="~ch\.ethz\.seb\.sebserver\.gui\..*" />
<Bug pattern="SE_BAD_FIELD" />
</Match>
<Match>
<Package name="ch.ethz.seb.sebserver.gui.content.*" />
<Package name="~ch\.ethz\.seb\.sebserver\.gui\.content\..*" />
<Bug pattern="RV_RETURN_VALUE_IGNORED_NO_SIDE_EFFECT" />
</Match>
<Match>

View file

@ -14,7 +14,9 @@ import org.joda.time.format.DateTimeFormatter;
/** Global Constants used in SEB Server web-service as well as in web-gui component */
public final class Constants {
public static final int SEB_FILE_HEADER_SIZE = 4;
public static final int JN_CRYPTOR_ITERATIONS = 10000;
public static final int JN_CRYPTOR_VERSION_HEADER_SIZE = 1;
public static final String TRUE_STRING = Boolean.TRUE.toString();
public static final String FALSE_STRING = Boolean.FALSE.toString();
@ -73,6 +75,7 @@ public final class Constants {
public static final String XML_PLIST_INTEGER = "integer";
public static final String OAUTH2_GRANT_TYPE_PASSWORD = "password";
public static final String OAUTH2_CLIENT_SECRET = "client_secret";
public static final String OAUTH2_GRANT_TYPE_REFRESH_TOKEN = "refresh_token";
public static final String OAUTH2_GRANT_TYPE_CLIENT_CREDENTIALS = "client_credentials";
public static final String OAUTH2_SCOPE_READ = "read";
@ -82,7 +85,7 @@ public final class Constants {
public static final int RWT_MOUSE_BUTTON_2 = 2;
public static final int RWT_MOUSE_BUTTON_3 = 3;
public static final int GZIP_HEADER_LENGTH = 10;
public static final int GZIP_HEADER_LENGTH = 4;
public static final int GZIP_ID1 = 0x1F;
public static final int GZIP_ID2 = 0x8B;
public static final int GZIP_CM = 8;

View file

@ -87,10 +87,14 @@ public class APIMessage implements Serializable {
Utils.asImmutableList(attributes));
}
public APIMessage of(final Throwable error) {
public APIMessage of(final Exception error) {
return new APIMessage(this.messageCode, this.systemMessage, error.getMessage());
}
public APIMessage of(final Exception error, final String... attributes) {
return new APIMessage(this.messageCode, this.systemMessage, error.getMessage(), Arrays.asList(attributes));
}
public ResponseEntity<List<APIMessage>> createErrorResponse() {
final APIMessage message = of();
return new ResponseEntity<>(

View file

@ -29,7 +29,7 @@ import org.slf4j.LoggerFactory;
* try {
* ... do some computation
* return Result.of(result);
* } catch (Throwable t) {
* } catch (Exception error) {
* return Result.ofError(t);
* }
* }
@ -57,14 +57,14 @@ public final class Result<T> {
/** The resulting value. May be null if an error occurred */
private final T value;
/** The error when happened otherwise null */
private final Throwable error;
private final Exception error;
private Result(final T value) {
this.value = value;
this.error = null;
}
private Result(final Throwable error) {
private Result(final Exception error) {
this.value = null;
this.error = error;
}
@ -80,7 +80,7 @@ public final class Result<T> {
*
* @param errorHandler the error handling function
* @return */
public T get(final Function<Throwable, T> errorHandler) {
public T get(final Function<Exception, T> errorHandler) {
return this.error != null ? errorHandler.apply(this.error) : this.value;
}
@ -90,7 +90,7 @@ public final class Result<T> {
* @param errorHandler the error handler to handle an error if happened
* @param supplier supplies an alternative result element on error case
* @return returns the referenced result element or the alternative element given by the supplier on error */
public T get(final Consumer<Throwable> errorHandler, final Supplier<T> supplier) {
public T get(final Consumer<Exception> errorHandler, final Supplier<T> supplier) {
if (this.error != null) {
errorHandler.accept(this.error);
return supplier.get();
@ -102,7 +102,7 @@ public final class Result<T> {
/** Apply a given error handler that consumes the error if there is one.
*
* @param errorHandler the error handler */
public void handleError(final Consumer<Throwable> errorHandler) {
public void handleError(final Consumer<Exception> errorHandler) {
if (this.error != null) {
errorHandler.accept(this.error);
}
@ -153,7 +153,7 @@ public final class Result<T> {
}
/** @return the error if some was reporter or null if there was no error */
public Throwable getError() {
public Exception getError() {
return this.error;
}
@ -243,7 +243,7 @@ public final class Result<T> {
*
* @param errorHandler the error handler
* @return self reference */
public Result<T> onError(final Consumer<Throwable> errorHandler) {
public Result<T> onError(final Consumer<Exception> errorHandler) {
if (this.error != null) {
errorHandler.accept(this.error);
}
@ -265,7 +265,7 @@ public final class Result<T> {
*
* @param error the error that is wrapped within the created Result
* @return Result of specified error */
public static <T> Result<T> ofError(final Throwable error) {
public static <T> Result<T> ofError(final Exception error) {
assert error != null : "error has null reference";
return new Result<>(error);
}

View file

@ -84,7 +84,6 @@ final class InstitutionalAuthenticationEntryPoint implements AuthenticationEntry
Charsets.UTF_8);
_defaultLogo = FileCopyUtils.copyToString(reader);
} catch (final IOException e) {
log.warn("Failed to load default logo image from filesystem: {}", defaultLogoFileName);
_defaultLogo = null;

View file

@ -585,7 +585,7 @@ public class ExamForm implements TemplateComposer {
private PageAction setSebRestriction(
final PageAction action,
final boolean sebRestriction,
final Consumer<Throwable> errorHandler) {
final Consumer<Exception> errorHandler) {
this.restService.getBuilder(SetExamSebRestriction.class)
.withURIVariable(

View file

@ -324,7 +324,7 @@ public class LmsSetupForm implements TemplateComposer {
// ... and handle the response
if (result.hasError()) {
if (formHandle.handleError(result.getError())) {
final Throwable error = result.getError();
final Exception error = result.getError();
if (error instanceof RestCallError) {
throw (RestCallError) error;
} else {

View file

@ -163,16 +163,23 @@ final class SebExamConfigImportPopup {
}
return true;
} else {
final Throwable error = configuration.getError();
final Exception 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));
.ifPresent(message -> {
if (APIMessage.ErrorMessage.MISSING_PASSWORD.isOf(message)) {
formHandle
.getContext()
.publishPageMessage(MISSING_PASSWORD);
} else {
formHandle
.getContext()
.notifyError(error);
}
});
return true;
}

View file

@ -203,7 +203,7 @@ public class SebExamConfigSettingsForm implements TemplateComposer {
}
}
private void notifyErrorOnSave(final Throwable error, final PageContext context) {
private void notifyErrorOnSave(final Exception error, final PageContext context) {
if (error instanceof APIMessageError) {
try {
final List<APIMessage> errorMessages = ((APIMessageError) error).getErrorMessages();
@ -215,7 +215,7 @@ public class SebExamConfigSettingsForm implements TemplateComposer {
}
} catch (final PageMessageException e) {
throw e;
} catch (final Throwable e) {
} catch (final Exception e) {
throw new RuntimeException(error);
}
}

View file

@ -301,7 +301,7 @@ public class ActivitiesPane implements TemplateComposer {
// SEB Client Logs
if (viewSebClientLogs) {
final TreeItem sebLogs = (monitoring != null)
final TreeItem sebLogs = (!isSupporter)
? this.widgetFactory.treeItemLocalized(
monitoring,
ActivityDefinition.SEB_CLIENT_LOGS.displayName)
@ -315,12 +315,10 @@ public class ActivitiesPane implements TemplateComposer {
.create());
}
if (monitoring != null) {
monitoring.setExpanded(
this.currentUser
.get()
.hasAnyRole(UserRole.EXAM_SUPPORTER));
}
monitoring.setExpanded(
this.currentUser
.get()
.hasAnyRole(UserRole.EXAM_SUPPORTER));
}
// ---- MONITORING ---------------------------------------------------------------------

View file

@ -121,7 +121,7 @@ public class FormHandle<T extends Entity> {
.getOrThrow();
}
public boolean handleError(final Throwable error) {
public boolean handleError(final Exception error) {
if (error instanceof RestCallError) {
((RestCallError) error)
.getErrorMessages()

View file

@ -384,7 +384,7 @@ public class ExamConfigurationServiceImpl implements ExamConfigurationService {
.call();
}
private String verifyErrorMessage(final Throwable error) {
private String verifyErrorMessage(final Exception error) {
if (error instanceof RestCallError) {
final List<APIMessage> errorMessages = ((RestCallError) error).getErrorMessages();
if (errorMessages.isEmpty()) {

View file

@ -186,15 +186,15 @@ public interface PageContext {
* optional exception instance
*
* @param errorMessage the error message to display
* @param error the error as Throwable */
void notifyError(String errorMessage, Throwable error);
* @param error the error as Exception */
void notifyError(String errorMessage, Exception error);
/** Shows an error message to the user with the message of the given Throwable.
/** Shows an error message to the user with the message of the given Exception.
* This mainly is used for debugging so far
*
* @param error the Throwable to display
* @param error the Exception to display
* @return adaption to be used with functional approaches */
<T> T notifyError(Throwable error);
<T> T notifyError(Exception error);
/** Publish and shows a message to the user with the given localized title and
* localized message. The message text can also be HTML text as far as RWT supports it.

View file

@ -156,7 +156,7 @@ public interface PageService {
* and forward to the login page with showing a successful logout message to the user. */
void logout(PageContext pageContext);
default <T> T logoutOnError(final Throwable t, final PageContext pageContext) {
default <T> T logoutOnError(final Exception t, final PageContext pageContext) {
log.error("Unexpected, Current User related error.Automatically logout and cleanup current user session. ", t);
logout(pageContext);
return null;

View file

@ -280,7 +280,7 @@ public class PageContextImpl implements PageContext {
}
@Override
public void notifyError(final String errorMessage, final Throwable error) {
public void notifyError(final String errorMessage, final Exception error) {
if (error instanceof APIMessageError) {
final List<APIMessage> errorMessages = ((APIMessageError) error).getErrorMessages();
final MessageBox messageBox = new Message(
@ -302,7 +302,7 @@ public class PageContextImpl implements PageContext {
}
@Override
public <T> T notifyError(final Throwable error) {
public <T> T notifyError(final Exception error) {
notifyError(error.getMessage(), error);
return null;
}

View file

@ -116,32 +116,32 @@ public abstract class RestCall<T> {
} else {
return handleRestCallError(responseEntity);
}
} catch (final RestClientResponseException responseError) {
} catch (final Exception e) {
final RestCallError restCallError = new RestCallError("Unexpected error while rest call", e);
final RestCallError restCallError = new RestCallError("Unexpected error while rest call", responseError);
try {
final String responseBody = ((RestClientResponseException) e).getResponseBodyAsString();
final String responseBody = responseError.getResponseBodyAsString();
restCallError.errors.addAll(RestCall.this.jsonMapper.readValue(
responseBody,
new TypeReference<List<APIMessage>>() {
}));
} catch (final ClassCastException cce) {
log.error("Unexpected error-response while webservice API call for: {}", builder, e);
restCallError.errors.add(APIMessage.ErrorMessage.UNEXPECTED.of(e));
} catch (final RuntimeException re) {
log.error("Unexpected runtime error while webservice API call for: {}", builder, re);
log.error("Unexpected runtime error cause: ", e);
restCallError.errors.add(APIMessage.ErrorMessage.UNEXPECTED.of(re));
} catch (final Exception ee) {
log.error("Unexpected error while webservice API call for: {}", builder, ee);
log.error("Unexpected error cause: ", e);
restCallError.errors.add(APIMessage.ErrorMessage.UNEXPECTED.of(ee));
} catch (final IOException e) {
restCallError.errors.add(APIMessage.ErrorMessage.UNEXPECTED.of(
responseError,
"NO RESPONSE AVAILABLE" + " cause: " + e.getMessage(),
String.valueOf(builder)));
}
return Result.ofError(restCallError);
} catch (final Exception e) {
final RestCallError restCallError = new RestCallError("Unexpected error while rest call", e);
restCallError.errors.add(APIMessage.ErrorMessage.UNEXPECTED.of(
e,
"NO RESPONSE AVAILABLE",
String.valueOf(builder)));
return Result.ofError(e);
}
}

View file

@ -62,7 +62,7 @@ public class CurrentUser {
return null;
}
public UserInfo getOrHandleError(final Function<Throwable, UserInfo> errorHandler) {
public UserInfo getOrHandleError(final Function<Exception, UserInfo> errorHandler) {
if (isAvailable()) {
return this.authContext
.getLoggedInUser()
@ -188,16 +188,23 @@ public class CurrentUser {
});
if (exchange.getStatusCodeValue() == HttpStatus.OK.value()) {
this.privileges = exchange.getBody().stream()
.reduce(new HashMap<RoleTypeKey, Privilege>(),
(map, priv) -> {
map.put(priv.roleTypeKey, priv);
return map;
},
(map1, map2) -> {
map1.putAll(map2);
return map1;
});
final Collection<Privilege> privileges = exchange.getBody();
if (privileges != null) {
this.privileges = privileges
.stream()
.reduce(new HashMap<RoleTypeKey, Privilege>(),
(map, priv) -> {
map.put(priv.roleTypeKey, priv);
return map;
},
(map1, map2) -> {
map1.putAll(map2);
return map1;
});
} else {
log.error("Failed to get Privileges from webservice API: {}", exchange);
return false;
}
return true;
} else {

View file

@ -298,7 +298,7 @@ public class OAuth2AuthorizationContextHolder implements AuthorizationContextHol
.contains(role.name());
}
private final class ErrorHandler extends OAuth2ErrorHandler {
private static final class ErrorHandler extends OAuth2ErrorHandler {
private ErrorHandler(final OAuth2ProtectedResourceDetails resource) {
super(resource);
}

View file

@ -261,7 +261,6 @@ public final class ClientConnectionTable {
private boolean changed = false;
private ClientConnectionData connectionData;
private int indicatorWeight;
//private int[] thresholdColorIndices;
private boolean duplicateChecked = false;
UpdatableTableItem(final Long connectionId) {
@ -349,6 +348,29 @@ public final class ClientConnectionTable {
.compare(this, other);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + getOuterType().hashCode();
result = prime * result + ((this.connectionId == null) ? 0 : this.connectionId.hashCode());
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final UpdatableTableItem other = (UpdatableTableItem) obj;
if (!getOuterType().equals(other.getOuterType()))
return false;
return compareTo(other) == 0;
}
int statusWeight() {
return ClientConnectionTable.this.statusData.statusWeight(this.connectionData);
}
@ -412,6 +434,10 @@ public final class ClientConnectionTable {
}
}
private ClientConnectionTable getOuterType() {
return ClientConnectionTable.this;
}
}
}

View file

@ -356,7 +356,7 @@ public class TableFilter<ROW extends Entity> {
try {
final org.joda.time.DateTime parse = org.joda.time.DateTime.parse(this.attribute.initValue);
this.selector.setDate(parse.getYear(), parse.getMonthOfYear() - 1, parse.getDayOfMonth());
} catch (final Exception e) {
} catch (final RuntimeException e) {
final org.joda.time.DateTime now = org.joda.time.DateTime.now(DateTimeZone.UTC);
this.selector.setDate(now.getYear(), now.getMonthOfYear() - 1, now.getDayOfMonth());
}
@ -436,7 +436,7 @@ public class TableFilter<ROW extends Entity> {
parse.getMonthOfYear() - 1,
parse.getDayOfMonth());
} catch (final Exception e) {
} catch (final RuntimeException e) {
this.fromSelector.setDate(
now.getYear(),
now.getMonthOfYear() - 1,

View file

@ -203,9 +203,19 @@ public class GridTable extends Composite {
private void adaptColumnWidth(final Event event) {
try {
this.columns.get(0).header.widthHint = 50;
this.columns.get(1).header.widthHint = 200;
final int currentTableWidth = super.getClientArea().width - ACTION_COLUMN_WIDTH;
final int widthUnit = currentTableWidth / this.columns
.stream()
.reduce(0,
(i, c2) -> i + c2.columnDef.widthFactor,
(i1, i2) -> i1 + i2);
this.columns
.stream()
.forEach(c -> c.header.widthHint = c.columnDef.widthFactor * widthUnit);
super.layout(true, true);
} catch (final Exception e) {
log.warn("Failed to adaptColumnWidth: ", e);
}

View file

@ -95,7 +95,7 @@ public interface BulkActionSupportDAO<T extends Entity> {
* @param error the error that shall be referred by created Result's
* @param all all entity keys to create error Result for
* @return List of Result refer to a given error for all given EntityKey instances */
static List<Result<EntityKey>> handleBulkActionError(final Throwable error, final Set<EntityKey> all) {
static List<Result<EntityKey>> handleBulkActionError(final Exception error, final Set<EntityKey> all) {
return all.stream()
.map(key -> Result.<EntityKey> ofError(new BulkActionEntityException(key)))
.collect(Collectors.toList());

View file

@ -168,8 +168,8 @@ public class ClientCredentialServiceImpl implements ClientCredentialService {
}
}
private final static char[] possibleCharacters = (new String(
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~`!@#$%^*()-_=+[{]}?"))
private final static char[] possibleCharacters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~`!@#$%^*()-_=+[{]}?"
.toCharArray();
private CharSequence generateClientId() {

View file

@ -45,7 +45,7 @@ public interface TransactionHandler {
*
* @see org.springframework.transaction.support.TransactionCallback#doInTransaction
* @see org.springframework.transaction.interceptor.TransactionAttribute#rollbackOn */
static void rollback(final Throwable t) {
static void rollback(final Exception t) {
TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
}

View file

@ -75,7 +75,7 @@ public interface LmsAPIService {
*
* @param filterMap the FilterMap containing the filter criteria
* @return true if the given QuizzData passes the filter */
public static Predicate<QuizData> quizFilterFunction(final FilterMap filterMap) {
public static Predicate<QuizData> quizFilterPredicate(final FilterMap filterMap) {
final String name = filterMap.getQuizName();
final DateTime from = filterMap.getQuizFromTime();
//final DateTime now = DateTime.now(DateTimeZone.UTC);
@ -92,10 +92,9 @@ public interface LmsAPIService {
* @param filterMap the FilterMap containing the filter criteria
* @return filtered list of QuizData */
public static Function<List<QuizData>, List<QuizData>> quizzesFilterFunction(final FilterMap filterMap) {
filterMap.getName();
return quizzes -> quizzes
.stream()
.filter(quizFilterFunction(filterMap))
.filter(quizFilterPredicate(filterMap))
.collect(Collectors.toList());
}

View file

@ -149,7 +149,7 @@ final class MockupLmsAPITemplate implements LmsAPITemplate {
final List<QuizData> quizzes = this.mockups
.stream()
.map(this::getExternalAddressAlias)
.filter(LmsAPIService.quizFilterFunction(filterMap))
.filter(LmsAPIService.quizFilterPredicate(filterMap))
.collect(Collectors.toList());
return quizzes;

View file

@ -229,7 +229,7 @@ final class OpenEdxCourseAccess {
public String end;
}
private class EdxOAuth2RequestAuthenticator implements OAuth2RequestAuthenticator {
private static final class EdxOAuth2RequestAuthenticator implements OAuth2RequestAuthenticator {
@Override
public void authenticate(

View file

@ -28,10 +28,12 @@ import org.springframework.security.oauth2.client.token.AccessTokenRequest;
import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsAccessTokenProvider;
import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.util.OAuth2Utils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import ch.ethz.seb.sebserver.ClientHttpRequestFactoryService;
import ch.ethz.seb.sebserver.gbl.Constants;
import ch.ethz.seb.sebserver.gbl.api.APIMessage;
import ch.ethz.seb.sebserver.gbl.model.Domain.LMS_SETUP;
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup;
@ -151,7 +153,7 @@ final class OpenEdxRestTemplateFactory {
/** A custom ClientCredentialsAccessTokenProvider that adapts the access token request to Open edX
* access token request protocol using a form-URL-encoded POST request according to:
* https://course-catalog-api-guide.readthedocs.io/en/latest/authentication/index.html#getting-an-access-token */
private class EdxClientCredentialsAccessTokenProvider extends ClientCredentialsAccessTokenProvider {
private static final class EdxClientCredentialsAccessTokenProvider extends ClientCredentialsAccessTokenProvider {
@Override
public OAuth2AccessToken obtainAccessToken(
@ -167,9 +169,9 @@ final class OpenEdxRestTemplateFactory {
headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
final MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("grant_type", "client_credentials");
params.add("client_id", resource.getClientId());
params.add("client_secret", resource.getClientSecret());
params.add(OAuth2Utils.GRANT_TYPE, Constants.OAUTH2_GRANT_TYPE_CLIENT_CREDENTIALS);
params.add(OAuth2Utils.CLIENT_ID, resource.getClientId());
params.add(Constants.OAUTH2_CLIENT_SECRET, resource.getClientSecret());
final OAuth2AccessToken retrieveToken = retrieveToken(request, resource, params, headers);
return retrieveToken;

View file

@ -21,7 +21,7 @@ public interface ZipService {
/** Use this to read uncompressed data from a given input-stream,
* compress this data with gzip and write the compressed data to
* a given output stream.
*
*
* @param out the OutputStream to write the compressed data to
* @param in the InputStream to read the uncompressed data from */
@Async(AsyncServiceSpringConfig.EXECUTOR_BEAN_NAME)
@ -30,7 +30,7 @@ public interface ZipService {
/** Use this to read gzip-compressed data from a given input-stream,
* uncompress this data and write the uncompressed data to
* a given output stream.
*
*
* @param out the OutputStream to write the uncompressed data to
* @param in the InputStream to read the compressed data from */
@Async(AsyncServiceSpringConfig.EXECUTOR_BEAN_NAME)

View file

@ -235,8 +235,8 @@ public class ClientConfigServiceImpl implements ClientConfigService {
? "true"
: "false",
(StringUtils.isNotBlank(config.fallbackStartURL))
? " <key>startURL</key>\r\n" +
" <string>" + config.fallbackStartURL + "</string>\r\n"
? " <key>startURL</key>%n" +
" <string>" + config.fallbackStartURL + "</string>%n"
: "",
this.webserviceInfo.getExternalServerURL(),
String.valueOf(config.institutionId),

View file

@ -216,15 +216,18 @@ public class ExamConfigIO {
InputStream unzip(final InputStream input) throws Exception {
final byte[] zipHeader = new byte[4];
input.read(zipHeader);
final byte[] zipHeader = new byte[Constants.GZIP_HEADER_LENGTH];
final int read = input.read(zipHeader);
if (read < Constants.GZIP_HEADER_LENGTH) {
throw new IllegalArgumentException("Failed to verify Zip type from input stream. Header size mismatch.");
}
final boolean isZipped = Byte.toUnsignedInt(zipHeader[0]) == Constants.GZIP_ID1
&& Byte.toUnsignedInt(zipHeader[1]) == Constants.GZIP_ID2
&& Byte.toUnsignedInt(zipHeader[2]) == Constants.GZIP_CM;
final InputStream sequencedInput = new SequenceInputStream(
new ByteArrayInputStream(zipHeader, 0, 4),
new ByteArrayInputStream(zipHeader, 0, Constants.GZIP_HEADER_LENGTH),
input);
if (isZipped) {

View file

@ -38,13 +38,12 @@ import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
import ch.ethz.seb.sebserver.gbl.util.Result;
import ch.ethz.seb.sebserver.webservice.servicelayer.client.ClientCredentialService;
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationAttributeDAO;
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.sebconfig.ConfigurationFormat;
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ConfigurationValueValidator;
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ExamConfigService;
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebConfigEncryptionService;
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebConfigEncryptionService.Strategy;
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ExamConfigService;
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ZipService;
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl.SebConfigEncryptionServiceImpl.EncryptionContext;
@ -57,7 +56,6 @@ public class ExamConfigServiceImpl implements ExamConfigService {
private final ExamConfigIO examConfigIO;
private final ConfigurationAttributeDAO configurationAttributeDAO;
private final ConfigurationDAO configurationDAO;
private final ExamConfigurationMapDAO examConfigurationMapDAO;
private final Collection<ConfigurationValueValidator> validators;
private final ClientCredentialService clientCredentialService;
@ -67,7 +65,6 @@ public class ExamConfigServiceImpl implements ExamConfigService {
protected ExamConfigServiceImpl(
final ExamConfigIO examConfigIO,
final ConfigurationAttributeDAO configurationAttributeDAO,
final ConfigurationDAO configurationDAO,
final ExamConfigurationMapDAO examConfigurationMapDAO,
final Collection<ConfigurationValueValidator> validators,
final ClientCredentialService clientCredentialService,
@ -76,7 +73,6 @@ public class ExamConfigServiceImpl implements ExamConfigService {
this.examConfigIO = examConfigIO;
this.configurationAttributeDAO = configurationAttributeDAO;
this.configurationDAO = configurationDAO;
this.examConfigurationMapDAO = examConfigurationMapDAO;
this.validators = validators;
this.clientCredentialService = clientCredentialService;
@ -366,14 +362,10 @@ public class ExamConfigServiceImpl implements ExamConfigService {
} catch (final Exception e) {
log.error("Unexpected error while trying to import SEB Exam Configuration: ", e);
log.debug("Make an undo on the ConfigurationNode to rollback the changes");
this.configurationDAO
.undo(config.configurationNodeId)
.getOrThrow();
if (streamDecrypted != null) {
final Exception exception = streamDecrypted.get();
if (exception != null) {
if (exception != null && exception instanceof APIMessageException) {
throw exception;
}
}

View file

@ -281,8 +281,8 @@ public class ExamConfigXMLParser extends DefaultHandler {
}
// check if we have a simple values array
if (attribute.type == AttributeType.MULTI_CHECKBOX_SELECTION
|| attribute.type == AttributeType.MULTI_SELECTION) {
if (attribute != null && (attribute.type == AttributeType.MULTI_CHECKBOX_SELECTION
|| attribute.type == AttributeType.MULTI_SELECTION)) {
saveValue(attrName, attribute, top.listIndex, (top.value == null) ? "" : top.value);
}

View file

@ -26,6 +26,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import ch.ethz.seb.sebserver.gbl.Constants;
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
import ch.ethz.seb.sebserver.gbl.util.Utils;
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebConfigCryptor;
@ -64,7 +65,7 @@ public class PasswordEncryptor implements SebConfigCryptor {
encryptOutput = new AES256JNCryptorOutputStream(
output,
Utils.toCharArray(context.getPassword()),
10000);
Constants.JN_CRYPTOR_ITERATIONS);
IOUtils.copyLarge(input, encryptOutput);
@ -98,8 +99,11 @@ public class PasswordEncryptor implements SebConfigCryptor {
final CharSequence password = context.getPassword();
try {
final byte[] version = new byte[4];
input.read(version);
final byte[] version = new byte[Constants.JN_CRYPTOR_VERSION_HEADER_SIZE];
final int read = input.read(version);
if (read != Constants.JN_CRYPTOR_VERSION_HEADER_SIZE) {
throw new IllegalArgumentException("Failed to verify RNCrypt version from input stream file header.");
}
final SequenceInputStream sequenceInputStream = new SequenceInputStream(
new ByteArrayInputStream(version),
@ -136,7 +140,7 @@ public class PasswordEncryptor implements SebConfigCryptor {
IOUtils.copy(sequenceInputStream, out);
final byte[] ciphertext = out.toByteArray();
final AES256JNCryptor cryptor = new AES256JNCryptor();
cryptor.setPBKDFIterations(10000);
cryptor.setPBKDFIterations(Constants.JN_CRYPTOR_ITERATIONS);
final byte[] decryptData = cryptor.decryptData(ciphertext, Utils.toCharArray(password));
final ByteArrayInputStream decryptedIn = new ByteArrayInputStream(decryptData);
IOUtils.copyLarge(decryptedIn, output);

View file

@ -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.Constants;
import ch.ethz.seb.sebserver.gbl.api.APIMessage;
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
import ch.ethz.seb.sebserver.gbl.util.Result;
@ -46,8 +47,6 @@ public final class SebConfigEncryptionServiceImpl implements SebConfigEncryption
private static final Logger log = LoggerFactory.getLogger(SebConfigEncryptionServiceImpl.class);
public static final int HEADER_SIZE = 4;
private final Map<Strategy, SebConfigCryptor> encryptors;
public SebConfigEncryptionServiceImpl(
@ -118,8 +117,12 @@ public final class SebConfigEncryptionServiceImpl implements SebConfigEncryption
pin = new PipedInputStream(pout);
Strategy strategy = null;
final byte[] header = new byte[HEADER_SIZE];
input.read(header);
final byte[] header = new byte[Constants.SEB_FILE_HEADER_SIZE];
final int read = input.read(header);
if (read != Constants.SEB_FILE_HEADER_SIZE) {
throw new IllegalArgumentException("Failed to read seb file header.");
}
for (final Strategy s : Strategy.values()) {
if (Arrays.equals(s.header, header)) {
strategy = s;