Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
b9153ab223
14 changed files with 234 additions and 171 deletions
12
README.rst
12
README.rst
|
@ -30,22 +30,12 @@ SEB Server provides a range of basic functionalities:
|
|||
- Automated SEB restriction on LMS side if the specified type of LMS supports the SEB restriction API
|
||||
- Monitoring and administration of SEB Client connections within a running exam
|
||||
|
||||
What is the SEB Server Setup repository?
|
||||
----------------------------------------
|
||||
|
||||
The SEB Server Setup repository contains predefined, docker-based installation directories for different installation proposes like demo, testing or production. The repository is completely separated from the SEB Server source repository and contains only files for setup-configuration and installation of a SEB Server infrastructure. The idea is that this repository can be cloned from a Server/VM on that the SEB Server has to be installed. One can then navigate to the directory with the needed setup and adapt the configuration files if needed. Then just use Docker to build up the SEB Server.
|
||||
|
||||
Install SEB Server
|
||||
------------------
|
||||
|
||||
For a complete guide to install SEB Server please go to `SEB Server Installation Guide <https://seb-server-setup.readthedocs.io/en/latest/overview.html>`_
|
||||
|
||||
Getting started with SEB Server
|
||||
-------------------------------
|
||||
|
||||
For a complete SEB Server user guide please go to `SEB Server User Guide <https://seb-server.readthedocs.io/en/latest/#>`_
|
||||
|
||||
Project Background
|
||||
------------------
|
||||
|
||||
TODO
|
||||
The SEB Server is currently build and maintained by the `Swiss MOOC Service <https://www.swissmooc.ch/>`_ that is founded by leading Swiss universities EPFL, ETH, SUPSI, USI and HES-SO and is financially supported by the `Swissuniversities’ P5 program <https://www.swissuniversities.ch/themen/digitalisierung/p-5-wissenschaftliche-information>`_.
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -18,7 +18,7 @@
|
|||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<sebserver-version>0.6.1</sebserver-version>
|
||||
<sebserver-version>0.6.2</sebserver-version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
</properties>
|
||||
|
|
|
@ -141,8 +141,8 @@ public final class API {
|
|||
|
||||
public static final String TEMPLATE_ATTRIBUTE_ENDPOINT = "/template-attribute";
|
||||
public static final String TEMPLATE_ATTRIBUTE_RESET_VALUES = "/reset";
|
||||
public static final String TEMPLATE_ATTRIBUTE_REMOVE_ORIENTATION = "remove-orientation";
|
||||
public static final String TEMPLATE_ATTRIBUTE_ATTACH_DEFAULT_ORIENTATION = "attach-default-orientation";
|
||||
public static final String TEMPLATE_ATTRIBUTE_REMOVE_ORIENTATION = "/remove-orientation";
|
||||
public static final String TEMPLATE_ATTRIBUTE_ATTACH_DEFAULT_ORIENTATION = "/attach-default-orientation";
|
||||
|
||||
public static final String ORIENTATION_ENDPOINT = "/orientation";
|
||||
public static final String VIEW_ENDPOINT = ORIENTATION_ENDPOINT + "/view";
|
||||
|
|
|
@ -52,7 +52,7 @@ 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.RestService;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.AttchDefaultOrientation;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.AttachDefaultOrientation;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetConfigAttributes;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetConfigurationValues;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetOrientations;
|
||||
|
@ -297,14 +297,14 @@ public class ExamConfigurationServiceImpl implements ExamConfigurationService {
|
|||
if (selection != null && !selection.isEmpty()) {
|
||||
selection.stream().forEach(entityKey -> {
|
||||
callTemplateAction(
|
||||
AttchDefaultOrientation.class,
|
||||
AttachDefaultOrientation.class,
|
||||
parentEntityKey.modelId,
|
||||
entityKey.modelId);
|
||||
});
|
||||
} else {
|
||||
final EntityKey entityKey = action.getEntityKey();
|
||||
callTemplateAction(
|
||||
AttchDefaultOrientation.class,
|
||||
AttachDefaultOrientation.class,
|
||||
parentEntityKey.modelId,
|
||||
entityKey.modelId);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ import java.util.function.Supplier;
|
|||
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.util.Cryptor;
|
||||
import org.eclipse.rap.rwt.RWT;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -36,6 +35,7 @@ import ch.ethz.seb.sebserver.gbl.model.Entity;
|
|||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Page;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Cryptor;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
import ch.ethz.seb.sebserver.gui.form.FormBuilder;
|
||||
import ch.ethz.seb.sebserver.gui.service.ResourceService;
|
||||
|
@ -227,7 +227,7 @@ public class PageServiceImpl implements PageService {
|
|||
final int dependencies = (int) entities.stream()
|
||||
.flatMap(entity -> {
|
||||
final RestCall<Set<EntityKey>>.RestCallBuilder builder =
|
||||
restService.getBuilder(
|
||||
restService.<Set<EntityKey>> getBuilder(
|
||||
entity.entityType(),
|
||||
CallType.GET_DEPENDENCIES);
|
||||
|
||||
|
@ -254,7 +254,7 @@ public class PageServiceImpl implements PageService {
|
|||
public <T extends Entity & Activatable> Function<PageAction, PageAction> activationToggleActionFunction(
|
||||
final EntityTable<T> table,
|
||||
final LocTextKey noSelectionText,
|
||||
Function<PageAction, PageAction> testBeforeActivation) {
|
||||
final Function<PageAction, PageAction> testBeforeActivation) {
|
||||
|
||||
return action -> {
|
||||
final Set<T> selectedROWData = table.getSelectedROWData();
|
||||
|
@ -269,7 +269,7 @@ public class PageServiceImpl implements PageService {
|
|||
for (final T entity : selectedROWData) {
|
||||
|
||||
if (!entity.isActive()) {
|
||||
RestCall<T>.RestCallBuilder restCallBuilder = restService.<T>getBuilder(
|
||||
final RestCall<T>.RestCallBuilder restCallBuilder = restService.<T> getBuilder(
|
||||
entityType,
|
||||
CallType.ACTIVATION_ACTIVATE)
|
||||
.withURIVariable(API.PARAM_MODEL_ID, entity.getModelId());
|
||||
|
@ -280,7 +280,7 @@ public class PageServiceImpl implements PageService {
|
|||
restCallBuilder
|
||||
.call()
|
||||
.onError(errors::add);
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
errors.add(e);
|
||||
}
|
||||
} else {
|
||||
|
@ -289,7 +289,7 @@ public class PageServiceImpl implements PageService {
|
|||
.onError(errors::add);
|
||||
}
|
||||
} else {
|
||||
restService.<T>getBuilder(entityType, CallType.ACTIVATION_DEACTIVATE)
|
||||
restService.<T> getBuilder(entityType, CallType.ACTIVATION_DEACTIVATE)
|
||||
.withURIVariable(API.PARAM_MODEL_ID, entity.getModelId())
|
||||
.call()
|
||||
.onError(errors::add);
|
||||
|
@ -347,7 +347,7 @@ public class PageServiceImpl implements PageService {
|
|||
|
||||
@Override
|
||||
public FormBuilder formBuilder(final PageContext pageContext, final int rows) {
|
||||
return new FormBuilder(this, pageContext, cryptor, rows);
|
||||
return new FormBuilder(this, pageContext, this.cryptor, rows);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -24,9 +24,9 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
|||
@Lazy
|
||||
@Component
|
||||
@GuiProfile
|
||||
public class AttchDefaultOrientation extends RestCall<TemplateAttribute> {
|
||||
public class AttachDefaultOrientation extends RestCall<TemplateAttribute> {
|
||||
|
||||
public AttchDefaultOrientation() {
|
||||
public AttachDefaultOrientation() {
|
||||
super(new TypeKey<>(
|
||||
CallType.SAVE,
|
||||
EntityType.CONFIGURATION_NODE,
|
|
@ -48,7 +48,10 @@ public final class ImageUploadSelection extends Composite {
|
|||
private static final long serialVersionUID = 368264811155804533L;
|
||||
private static final Logger log = LoggerFactory.getLogger(ImageUploadSelection.class);
|
||||
|
||||
public static final Set<String> SUPPORTED_IMAGE_FILES = Set.of(".png", ".jpg", ".jpeg");
|
||||
public static final Set<String> SUPPORTED_IMAGE_FILES = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
|
||||
".png",
|
||||
".jpg",
|
||||
".jpeg")));
|
||||
|
||||
private final ServerPushService serverPushService;
|
||||
|
||||
|
|
|
@ -12,14 +12,11 @@ import java.io.OutputStream;
|
|||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.security.oauth2.provider.ClientDetails;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.SebClientConfig;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.impl.BulkActionEvent;
|
||||
|
||||
public interface ClientConfigService {
|
||||
|
||||
|
@ -63,7 +60,6 @@ public interface ClientConfigService {
|
|||
/** Internally used to check OAuth2 access for a active SebClientConfig.
|
||||
*
|
||||
* @param config the SebClientConfig to check access
|
||||
* @return true if the system was able to gain an access token for the client. False otherwise
|
||||
*/
|
||||
* @return true if the system was able to gain an access token for the client. False otherwise */
|
||||
boolean checkAccess(SebClientConfig config);
|
||||
}
|
||||
|
|
|
@ -8,10 +8,41 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PipedInputStream;
|
||||
import java.io.PipedOutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.oauth2.provider.ClientDetails;
|
||||
import org.springframework.security.oauth2.provider.client.BaseClientDetails;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import ch.ethz.seb.sebserver.WebSecurityConfig;
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||
import ch.ethz.seb.sebserver.gbl.model.institution.Institution;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.SebClientConfig;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||
|
@ -28,39 +59,6 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebConfigEncrypti
|
|||
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ZipService;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl.SebConfigEncryptionServiceImpl.EncryptionContext;
|
||||
import ch.ethz.seb.sebserver.webservice.weblayer.oauth.WebserviceResourceConfiguration;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.provider.ClientDetails;
|
||||
import org.springframework.security.oauth2.provider.client.BaseClientDetails;
|
||||
import org.springframework.security.oauth2.provider.token.TokenStore;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PipedInputStream;
|
||||
import java.io.PipedOutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.UUID;
|
||||
|
||||
@Lazy
|
||||
@Service
|
||||
|
@ -71,35 +69,35 @@ public class ClientConfigServiceImpl implements ClientConfigService {
|
|||
|
||||
private static final String SEB_CLIENT_CONFIG_TEMPLATE_XML =
|
||||
" <dict>\r\n" +
|
||||
" <key>sebMode</key>\r\n" +
|
||||
" <integer>1</integer>\r\n" +
|
||||
" <key>sebConfigPurpose</key>\r\n" +
|
||||
" <integer>%s</integer>\r\n" +
|
||||
" <key>sebServerFallback</key>\r\n" +
|
||||
" <%s />\r\n" +
|
||||
"%s" +
|
||||
" <key>sebServerURL</key>\r\n" +
|
||||
" <string>%s</string>\r\n" +
|
||||
" <key>sebServerConfiguration</key>\r\n" +
|
||||
" <dict>\r\n" +
|
||||
" <key>institution</key>\r\n" +
|
||||
" <string>%s</string>\r\n" +
|
||||
" <key>clientName</key>\r\n" +
|
||||
" <string>%s</string>\r\n" +
|
||||
" <key>clientSecret</key>\r\n" +
|
||||
" <string>%s</string>\r\n" +
|
||||
" <key>apiDiscovery</key>\r\n" +
|
||||
" <string>%s</string>\r\n" +
|
||||
" </dict>\r\n" +
|
||||
" </dict>\r\n";
|
||||
" <key>sebMode</key>\r\n" +
|
||||
" <integer>1</integer>\r\n" +
|
||||
" <key>sebConfigPurpose</key>\r\n" +
|
||||
" <integer>%s</integer>\r\n" +
|
||||
" <key>sebServerFallback</key>\r\n" +
|
||||
" <%s />\r\n" +
|
||||
"%s" +
|
||||
" <key>sebServerURL</key>\r\n" +
|
||||
" <string>%s</string>\r\n" +
|
||||
" <key>sebServerConfiguration</key>\r\n" +
|
||||
" <dict>\r\n" +
|
||||
" <key>institution</key>\r\n" +
|
||||
" <string>%s</string>\r\n" +
|
||||
" <key>clientName</key>\r\n" +
|
||||
" <string>%s</string>\r\n" +
|
||||
" <key>clientSecret</key>\r\n" +
|
||||
" <string>%s</string>\r\n" +
|
||||
" <key>apiDiscovery</key>\r\n" +
|
||||
" <string>%s</string>\r\n" +
|
||||
" </dict>\r\n" +
|
||||
" </dict>\r\n";
|
||||
|
||||
private final static String SEB_CLIENT_CONFIG_INTEGER_TEMPLATE =
|
||||
" <key>%s</key>\r\n" +
|
||||
" <integer>%s</integer>\r\n";
|
||||
" <integer>%s</integer>\r\n";
|
||||
|
||||
private final static String SEB_CLIENT_CONFIG_STRING_TEMPLATE =
|
||||
" <key>%s</key>\r\n" +
|
||||
" <string>%s</string>\r\n";
|
||||
" <string>%s</string>\r\n";
|
||||
|
||||
private final InstitutionDAO institutionDAO;
|
||||
private final SebClientConfigDAO sebClientConfigDAO;
|
||||
|
@ -107,7 +105,6 @@ public class ClientConfigServiceImpl implements ClientConfigService {
|
|||
private final SebConfigEncryptionService sebConfigEncryptionService;
|
||||
private final PasswordEncoder clientPasswordEncoder;
|
||||
private final ZipService zipService;
|
||||
private final TokenStore tokenStore;
|
||||
private final WebserviceInfo webserviceInfo;
|
||||
|
||||
protected ClientConfigServiceImpl(
|
||||
|
@ -116,7 +113,6 @@ public class ClientConfigServiceImpl implements ClientConfigService {
|
|||
final ClientCredentialService clientCredentialService,
|
||||
final SebConfigEncryptionService sebConfigEncryptionService,
|
||||
final ZipService zipService,
|
||||
final TokenStore tokenStore,
|
||||
@Qualifier(WebSecurityConfig.CLIENT_PASSWORD_ENCODER_BEAN_NAME) final PasswordEncoder clientPasswordEncoder,
|
||||
final WebserviceInfo webserviceInfo) {
|
||||
|
||||
|
@ -126,7 +122,6 @@ public class ClientConfigServiceImpl implements ClientConfigService {
|
|||
this.sebConfigEncryptionService = sebConfigEncryptionService;
|
||||
this.zipService = zipService;
|
||||
this.clientPasswordEncoder = clientPasswordEncoder;
|
||||
this.tokenStore = tokenStore;
|
||||
this.webserviceInfo = webserviceInfo;
|
||||
}
|
||||
|
||||
|
@ -279,7 +274,7 @@ public class ClientConfigServiceImpl implements ClientConfigService {
|
|||
config.fallbackAttemptInterval);
|
||||
|
||||
if (StringUtils.isNotBlank(config.fallbackPassword)) {
|
||||
CharSequence decrypt = clientCredentialService.decrypt(config.fallbackPassword);
|
||||
final CharSequence decrypt = this.clientCredentialService.decrypt(config.fallbackPassword);
|
||||
fallbackAddition += String.format(
|
||||
SEB_CLIENT_CONFIG_STRING_TEMPLATE,
|
||||
SebClientConfig.ATTR_FALLBACK_PASSWORD,
|
||||
|
@ -287,7 +282,7 @@ public class ClientConfigServiceImpl implements ClientConfigService {
|
|||
}
|
||||
|
||||
if (StringUtils.isNotBlank(config.quitPassword)) {
|
||||
CharSequence decrypt = clientCredentialService.decrypt(config.quitPassword);
|
||||
final CharSequence decrypt = this.clientCredentialService.decrypt(config.quitPassword);
|
||||
fallbackAddition += String.format(
|
||||
SEB_CLIENT_CONFIG_STRING_TEMPLATE,
|
||||
SebClientConfig.ATTR_QUIT_PASSWORD,
|
||||
|
@ -323,34 +318,34 @@ public class ClientConfigServiceImpl implements ClientConfigService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean checkAccess(SebClientConfig config) {
|
||||
if(!config.isActive()) {
|
||||
public boolean checkAccess(final SebClientConfig config) {
|
||||
if (!config.isActive()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
String externalServerURL = webserviceInfo.getExternalServerURL() +
|
||||
final RestTemplate restTemplate = new RestTemplate();
|
||||
final String externalServerURL = this.webserviceInfo.getExternalServerURL() +
|
||||
API.OAUTH_TOKEN_ENDPOINT;
|
||||
|
||||
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
|
||||
final MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
|
||||
headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
|
||||
ClientCredentials credentials = sebClientConfigDAO
|
||||
final ClientCredentials credentials = this.sebClientConfigDAO
|
||||
.getSebClientCredentials(config.getModelId())
|
||||
.getOrThrow();
|
||||
CharSequence plainClientSecret = clientCredentialService.getPlainClientSecret(credentials);
|
||||
String basicAuth = credentials.clientId +
|
||||
final CharSequence plainClientSecret = this.clientCredentialService.getPlainClientSecret(credentials);
|
||||
final String basicAuth = credentials.clientId +
|
||||
String.valueOf(Constants.COLON) +
|
||||
plainClientSecret;
|
||||
String encoded = Base64.getEncoder()
|
||||
final String encoded = Base64.getEncoder()
|
||||
.encodeToString(basicAuth.getBytes());
|
||||
|
||||
headers.add(HttpHeaders.AUTHORIZATION, "Basic " + encoded);
|
||||
HttpEntity<String> entity = new HttpEntity<>(
|
||||
final HttpEntity<String> entity = new HttpEntity<>(
|
||||
"grant_type=client_credentials&scope=read write",
|
||||
headers);
|
||||
|
||||
ResponseEntity<String> exchange = restTemplate.exchange(
|
||||
final ResponseEntity<String> exchange = restTemplate.exchange(
|
||||
externalServerURL,
|
||||
HttpMethod.POST,
|
||||
entity,
|
||||
|
@ -362,25 +357,12 @@ public class ClientConfigServiceImpl implements ClientConfigService {
|
|||
log.warn("Failed to check access SebClientConfig {} response: {}", config, exchange.getStatusCode());
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
log.warn("Failed to check access for SebClientConfig: {} cause: {}", config, e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void flushClientConfigData(final EntityKey key) {
|
||||
try {
|
||||
final String clientName = this.sebClientConfigDAO.getSebClientCredentials(key.modelId)
|
||||
.getOrThrow()
|
||||
.clientIdAsString();
|
||||
|
||||
final Collection<OAuth2AccessToken> tokensByClientId = this.tokenStore.findTokensByClientId(clientName);
|
||||
tokensByClientId.forEach(this.tokenStore::removeAccessToken);
|
||||
} catch (final Exception e) {
|
||||
log.error("Unexpected error while trying to flush ClientConfig data for {}", key, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void passwordEncryption(
|
||||
final OutputStream output,
|
||||
final CharSequence encryptionPassword,
|
||||
|
|
|
@ -276,7 +276,7 @@ public class ConfigurationNodeController extends EntityController<ConfigurationN
|
|||
EntityType.CONFIGURATION_NODE))));
|
||||
}
|
||||
|
||||
Configuration config = doImport
|
||||
final Configuration config = doImport
|
||||
.getOrThrow();
|
||||
|
||||
return this.configurationDAO
|
||||
|
@ -353,15 +353,16 @@ public class ConfigurationNodeController extends EntityController<ConfigurationN
|
|||
filterMap)
|
||||
.getOrThrow();
|
||||
|
||||
final int start = (pageNumber - 1) * pageSize;
|
||||
int end = start + pageSize;
|
||||
final int start = (this.paginationService.getPageNumber(pageNumber) - 1) *
|
||||
this.paginationService.getPageSize(pageSize);
|
||||
int end = start + this.paginationService.getPageSize(pageSize);
|
||||
if (attrs.size() < end) {
|
||||
end = attrs.size();
|
||||
}
|
||||
|
||||
return new Page<>(
|
||||
attrs.size() / pageSize,
|
||||
pageNumber,
|
||||
attrs.size() / this.paginationService.getPageSize(pageSize),
|
||||
this.paginationService.getPageNumber(pageNumber),
|
||||
sort,
|
||||
attrs.subList(start, end));
|
||||
}
|
||||
|
|
|
@ -8,6 +8,30 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.webservice.weblayer.api;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PipedInputStream;
|
||||
import java.io.PipedOutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.mybatis.dynamic.sql.SqlTable;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import org.springframework.validation.FieldError;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.api.APIMessage;
|
||||
|
@ -25,29 +49,6 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.dao.SebClientConfigDAO;
|
|||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ClientConfigService;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.validation.BeanValidationService;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.mybatis.dynamic.sql.SqlTable;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import org.springframework.validation.FieldError;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PipedInputStream;
|
||||
import java.io.PipedOutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
@WebServiceProfile
|
||||
@RestController
|
||||
|
@ -146,16 +147,16 @@ public class SebClientConfigController extends ActivatableEntityController<SebCl
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Result<SebClientConfig> notifySaved(SebClientConfig entity) {
|
||||
protected Result<SebClientConfig> notifySaved(final SebClientConfig entity) {
|
||||
if (entity.isActive()) {
|
||||
// try to get access token for SEB client
|
||||
sebClientConfigService.checkAccess(entity);
|
||||
this.sebClientConfigService.checkAccess(entity);
|
||||
}
|
||||
return super.notifySaved(entity);
|
||||
}
|
||||
|
||||
private SebClientConfig checkPasswordMatch(final SebClientConfig entity) {
|
||||
Collection<APIMessage> errors = new ArrayList<>();
|
||||
final Collection<APIMessage> errors = new ArrayList<>();
|
||||
if (entity.hasEncryptionSecret() && !entity.encryptSecret.equals(entity.encryptSecretConfirm)) {
|
||||
errors.add(APIMessage.fieldValidationError(
|
||||
new FieldError(
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
spring.application.name=SEB Server
|
||||
spring.profiles.active=dev
|
||||
sebserver.version=0.6.1 (RC for v1.0)
|
||||
sebserver.version=0.6.2 (RC for v1.0)
|
||||
|
||||
##########################################################
|
||||
### Global Server Settings
|
||||
|
|
|
@ -10,9 +10,6 @@ package ch.ethz.seb.sebserver.gui.integration;
|
|||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.junit.Before;
|
||||
|
@ -22,7 +19,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.http.client.SimpleClientHttpRequestFactory;
|
||||
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
||||
import org.springframework.security.web.FilterChainProxy;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
@ -79,18 +76,7 @@ public abstract class GuiIntegrationTest {
|
|||
final ClientHttpRequestFactoryService clientHttpRequestFactoryService = Mockito
|
||||
.mock(ClientHttpRequestFactoryService.class);
|
||||
Mockito.when(clientHttpRequestFactoryService.getClientHttpRequestFactory()).thenReturn(
|
||||
Result.of(
|
||||
new SimpleClientHttpRequestFactory() {
|
||||
|
||||
@Override
|
||||
protected void prepareConnection(
|
||||
final HttpURLConnection connection,
|
||||
final String httpMethod) throws IOException {
|
||||
|
||||
super.prepareConnection(connection, httpMethod);
|
||||
connection.setInstanceFollowRedirects(false);
|
||||
}
|
||||
}));
|
||||
Result.of(new HttpComponentsClientHttpRequestFactory()));
|
||||
|
||||
return new OAuth2AuthorizationContextHolder(
|
||||
this.clientId,
|
||||
|
|
|
@ -65,6 +65,7 @@ import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues.TableV
|
|||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.SebClientConfig;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.TemplateAttribute;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.View;
|
||||
import ch.ethz.seb.sebserver.gbl.model.user.PasswordChange;
|
||||
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
||||
|
@ -104,6 +105,7 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.
|
|||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.GetClientConfigPage;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.NewClientConfig;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.SaveClientConfig;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.AttachDefaultOrientation;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.CopyConfiguration;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.ExportPlainXML;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetConfigAttributes;
|
||||
|
@ -125,6 +127,8 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.Ge
|
|||
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.service.remote.webservice.api.seb.examconfig.NewExamConfig;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.RemoveOrientation;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.ResetTemplateValues;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.SaveExamConfig;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.SaveExamConfigHistory;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.SaveExamConfigTableValues;
|
||||
|
@ -1544,8 +1548,12 @@ public class UseCasesIntegrationTest extends GuiIntegrationTest {
|
|||
@Order(15)
|
||||
// *************************************
|
||||
// Use Case 15: Login as examAdmin2 and get views and orientations
|
||||
// - test Views API
|
||||
// - create configuration template form existing configuration
|
||||
// - Test Views API
|
||||
// - Create configuration template form existing configuration
|
||||
// - Check views and orientation created for template
|
||||
// - Remove one template attribute from orientation
|
||||
// - Change one template attribute value
|
||||
// - Reset template values
|
||||
public void testUsecase15() throws IOException {
|
||||
final RestServiceImpl restService = createRestServiceForUser(
|
||||
"examAdmin2",
|
||||
|
@ -1557,7 +1565,14 @@ public class UseCasesIntegrationTest extends GuiIntegrationTest {
|
|||
new CopyConfiguration(),
|
||||
new GetTemplateAttributePage(),
|
||||
new GetExamConfigNodePage(),
|
||||
new GetTemplateAttribute());
|
||||
new GetTemplateAttribute(),
|
||||
new GetConfigurationValues(),
|
||||
new GetConfigurationValuePage(),
|
||||
new SaveExamConfigValue(),
|
||||
new GetFollowupConfiguration(),
|
||||
new RemoveOrientation(),
|
||||
new AttachDefaultOrientation(),
|
||||
new ResetTemplateValues());
|
||||
|
||||
final List<View> views = restService
|
||||
.getBuilder(GetViews.class)
|
||||
|
@ -1572,6 +1587,7 @@ public class UseCasesIntegrationTest extends GuiIntegrationTest {
|
|||
.getBuilder(GetOrientations.class)
|
||||
.call()
|
||||
.getOrThrow();
|
||||
assertNotNull(orientations);
|
||||
orientations.forEach(o -> assertEquals(o.templateId, ConfigurationNode.DEFAULT_TEMPLATE_ID));
|
||||
|
||||
// get configuration page and first config from the page to copy as template
|
||||
|
@ -1612,7 +1628,95 @@ public class UseCasesIntegrationTest extends GuiIntegrationTest {
|
|||
assertNotNull(newTemplate);
|
||||
assertEquals("Config Template", newTemplate.name);
|
||||
|
||||
assertNotNull(orientations);
|
||||
// check views for template where created
|
||||
final List<View> templateViews = restService
|
||||
.getBuilder(GetViews.class)
|
||||
.withQueryParam(View.FILTER_ATTR_TEMPLATE, String.valueOf(template.id))
|
||||
.call()
|
||||
.getOrThrow();
|
||||
|
||||
assertNotNull(templateViews);
|
||||
assertFalse(templateViews.isEmpty());
|
||||
assertEquals(11, templateViews.size());
|
||||
|
||||
// check orientations for template where created
|
||||
final List<Orientation> templateTrientations = restService
|
||||
.getBuilder(GetOrientations.class)
|
||||
.withQueryParam(Orientation.FILTER_ATTR_TEMPLATE_ID, String.valueOf(template.id))
|
||||
.call()
|
||||
.getOrThrow();
|
||||
assertNotNull(templateTrientations);
|
||||
assertFalse(templateTrientations.isEmpty());
|
||||
assertEquals(192, templateTrientations.size());
|
||||
|
||||
// get template attributes page
|
||||
final Page<TemplateAttribute> templateAttributes = restService
|
||||
.getBuilder(GetTemplateAttributePage.class)
|
||||
.withURIVariable(API.PARAM_PARENT_MODEL_ID, String.valueOf(template.id))
|
||||
.call()
|
||||
.getOrThrow();
|
||||
|
||||
assertNotNull(templateAttributes);
|
||||
assertFalse(templateAttributes.isEmpty());
|
||||
final TemplateAttribute templateAttr = templateAttributes.content.get(0);
|
||||
assertEquals(template.id, templateAttr.templateId);
|
||||
final Orientation orientation = templateAttr.getOrientation();
|
||||
assertNotNull(orientation);
|
||||
|
||||
TemplateAttribute savedTAttribute = restService
|
||||
.getBuilder(RemoveOrientation.class)
|
||||
.withURIVariable(API.PARAM_PARENT_MODEL_ID, String.valueOf(template.id))
|
||||
.withURIVariable(API.PARAM_MODEL_ID, templateAttr.getModelId())
|
||||
.call()
|
||||
.getOrThrow();
|
||||
|
||||
assertNotNull(savedTAttribute);
|
||||
assertNull(savedTAttribute.getOrientation());
|
||||
|
||||
// Re-attach default orientation
|
||||
savedTAttribute = restService
|
||||
.getBuilder(AttachDefaultOrientation.class)
|
||||
.withURIVariable(API.PARAM_PARENT_MODEL_ID, String.valueOf(template.id))
|
||||
.withURIVariable(API.PARAM_MODEL_ID, templateAttr.getModelId())
|
||||
.call()
|
||||
.getOrThrow();
|
||||
|
||||
assertNotNull(savedTAttribute);
|
||||
assertNotNull(savedTAttribute.getOrientation());
|
||||
assertEquals(orientation.viewId, savedTAttribute.getOrientation().viewId);
|
||||
assertEquals(orientation.templateId, savedTAttribute.getOrientation().templateId);
|
||||
assertEquals(orientation.attributeId, savedTAttribute.getOrientation().attributeId);
|
||||
|
||||
// get first value and change it
|
||||
final Configuration fallow_up = restService.getBuilder(GetFollowupConfiguration.class)
|
||||
.withURIVariable(API.PARAM_MODEL_ID, String.valueOf(template.id))
|
||||
.call()
|
||||
.getOrThrow();
|
||||
assertNotNull(fallow_up);
|
||||
|
||||
final List<ConfigurationValue> values = restService
|
||||
.getBuilder(GetConfigurationValues.class)
|
||||
.withQueryParam(ConfigurationValue.FILTER_ATTR_CONFIGURATION_ID, String.valueOf(fallow_up.id))
|
||||
.withQueryParam(ConfigurationValue.FILTER_ATTR_CONFIGURATION_ATTRIBUTE_ID, savedTAttribute.getModelId())
|
||||
.call()
|
||||
.getOrThrow();
|
||||
|
||||
assertNotNull(values);
|
||||
assertTrue(values.size() == 1);
|
||||
final ConfigurationValue templateValue = values.get(0);
|
||||
assertNull(templateValue.value);
|
||||
|
||||
final ConfigurationValue newValue = new ConfigurationValue(
|
||||
templateValue.id, templateValue.institutionId, savedTAttribute.getTemplateId(),
|
||||
templateValue.attributeId, 0, "123");
|
||||
final ConfigurationValue newTemplValue = restService
|
||||
.getBuilder(SaveExamConfigValue.class)
|
||||
.withBody(newValue)
|
||||
.call()
|
||||
.getOrThrow();
|
||||
assertNotNull(newTemplValue);
|
||||
assertEquals("123", newTemplValue.value);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue