From 9b12d04daa0a3c0c10461dea163ba98de2a34f7e Mon Sep 17 00:00:00 2001 From: anhefti Date: Tue, 20 Aug 2019 17:19:15 +0200 Subject: [PATCH] prepare for prod --- docker/demo/Dockerfile | 10 +- docker/gencerts/Dockerfile | 25 +- docker/gencerts/gencerts.sh | 9 - docker/prod/standalone/selfsigned/Dockerfile | 48 ++ .../standalone/selfsigned/docker-compose.yml | 53 ++ .../standalone/selfsigned/gencerts/Dockerfile | 30 ++ docker/prod/standalone/selfsigned/mariadb.cnf | 9 + pom.xml | 3 +- .../ethz/seb/sebserver/WebSecurityConfig.java | 20 +- ...InstitutionalAuthenticationEntryPoint.java | 6 + .../config/application-dev-ws.properties | 2 +- src/main/resources/data-prod.sql | 14 + src/main/resources/schema-prod.sql | 474 ++++++++++++++++++ 13 files changed, 673 insertions(+), 30 deletions(-) delete mode 100644 docker/gencerts/gencerts.sh create mode 100644 docker/prod/standalone/selfsigned/Dockerfile create mode 100644 docker/prod/standalone/selfsigned/docker-compose.yml create mode 100644 docker/prod/standalone/selfsigned/gencerts/Dockerfile create mode 100644 docker/prod/standalone/selfsigned/mariadb.cnf create mode 100644 src/main/resources/data-prod.sql create mode 100644 src/main/resources/schema-prod.sql diff --git a/docker/demo/Dockerfile b/docker/demo/Dockerfile index 85f12814..ec3c67fe 100644 --- a/docker/demo/Dockerfile +++ b/docker/demo/Dockerfile @@ -7,7 +7,7 @@ RUN git clone -b "$GIT_TAG" --depth 1 https://github.com/SafeExamBrowser/seb-ser FROM maven:3.5-jdk-8-alpine -ARG JAR_VERSION +ARG SEBSERVER_VERSION WORKDIR /demo COPY --from=0 /demo/seb-server /demo @@ -15,14 +15,14 @@ RUN mvn clean install -e -P Demo -DskipTests FROM openjdk:8-jre-alpine -ARG JAR_VERSION -ENV JAR_VERSION ${JAR_VERSION} +ARG SEBSERVER_VERSION +ENV SEBSERVER_VERSION ${SEBSERVER_VERSION} WORKDIR /demo -COPY --from=1 /demo/target/seb-server-"$JAR_VERSION".jar /demo +COPY --from=1 /demo/target/seb-server-"$SEBSERVER_VERSION".jar /demo ENTRYPOINT ["sh", "-c"] -CMD ["java -jar seb-server-${JAR_VERSION}.jar --spring.config.location=classpath:/config/,file:/demo/externalResources/ --server.address=0.0.0.0 --spring.profiles.active=demo"] +CMD ["java -jar seb-server-${SEBSERVER_VERSION}.jar --spring.config.location=classpath:/config/,file:/demo/externalResources/ --server.address=0.0.0.0 --spring.profiles.active=demo"] EXPOSE 8080 \ No newline at end of file diff --git a/docker/gencerts/Dockerfile b/docker/gencerts/Dockerfile index 2f18f40a..2a900f91 100644 --- a/docker/gencerts/Dockerfile +++ b/docker/gencerts/Dockerfile @@ -1,11 +1,14 @@ -FROM debian:jessie +FROM openjdk:11-jre-stretch RUN apt-get update && apt-get install -y openssl +ENV KEYSTORE_PWD= +ENV SERVER_CN="localhost" +ENV CLIENT_CN="localhost" ENV OPENSSL_SUBJ="/C=CH/ST=Zuerich/L=Zuerich" ENV OPENSSL_CA="${OPENSSL_SUBJ}/CN=demo-CA" -ENV OPENSSL_SERVER="${OPENSSL_SUBJ}/CN=demo-server" -ENV OPENSSL_CLIENT="${OPENSSL_SUBJ}/CN=demo-client" +ENV OPENSSL_SERVER="${OPENSSL_SUBJ}/CN=${SERVER_CN}" +ENV OPENSSL_CLIENT="${OPENSSL_SUBJ}/CN=${CLIENT_CN}" COPY gencerts.sh / RUN chmod +x /gencerts.sh @@ -15,7 +18,19 @@ VOLUME /certs WORKDIR /certs # This works on windows -CMD openssl genrsa -out ca-key.pem 2048 && openssl req -new -x509 -key ca-key.pem -nodes -days 3600 -subj "${OPENSSL_CA}" -out ca.pem && openssl req -newkey rsa:2048 -days 3600 -nodes -subj "${OPENSSL_SERVER}" -keyout server-key.pem -out server-req.pem && openssl rsa -in server-key.pem -out server-key.pem && openssl x509 -req -in server-req.pem -days 3600 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem && openssl req -newkey rsa:2048 -days 3600 -nodes -subj "${OPENSSL_CLIENT}" -keyout client-key.pem -out client-req.pem && openssl rsa -in client-key.pem -out client-key.pem && openssl x509 -req -in client-req.pem -days 3600 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem && openssl verify -CAfile ca.pem server-cert.pem client-cert.pem && openssl x509 -in ca.pem -inform pem -out ca.der -outform der +CMD openssl genrsa -out ca-key.pem 2048 \ + && openssl req -new -x509 -key ca-key.pem -nodes -days 3600 -subj "${OPENSSL_CA}" -out ca.pem \ + && openssl req -newkey rsa:2048 -days 3600 -nodes -subj "${OPENSSL_SERVER}" -keyout server-key.pem -out server-req.pem \ + && openssl rsa -in server-key.pem -out server-key.pem \ + && openssl x509 -req -in server-req.pem -days 3600 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem \ + && openssl req -newkey rsa:2048 -days 3600 -nodes -subj "${OPENSSL_CLIENT}" -keyout client-key.pem -out client-req.pem \ + && openssl rsa -in client-key.pem -out client-key.pem \ + && openssl x509 -req -in client-req.pem -days 3600 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem \ + && openssl verify -CAfile ca.pem server-cert.pem client-cert.pem \ + && openssl x509 -in ca.pem -inform pem -out ca.der -outform der \ + && openssl pkcs12 -export -out client-cert.pkcs12 -in client-cert.pem -inkey client-key.pem -passout pass:"${KEYSTORE_PWD}" \ + && keytool -importkeystore -destkeystore seb-server-keystore.pkcs12 -deststorepass "${KEYSTORE_PWD}" -srckeystore client-cert.pkcs12 -srcstoretype PKCS12 -srcstorepass "${KEYSTORE_PWD}" \ + && keytool -import -file ca.pem -keystore seb-server-truststore.pkcs12 -storepass "${KEYSTORE_PWD}" -srcstoretype PKCS12 -noprompt -# This don't work on windows +# This doesn't work on windows!? #CMD /gencerts.sh \ No newline at end of file diff --git a/docker/gencerts/gencerts.sh b/docker/gencerts/gencerts.sh deleted file mode 100644 index b86ccebf..00000000 --- a/docker/gencerts/gencerts.sh +++ /dev/null @@ -1,9 +0,0 @@ -openssl genrsa -out ca-key.pem 2048 -openssl req -new -x509 -key ca-key.pem -nodes -days 3600 -subj "${OPENSSL_CA}" -out ca.pem -openssl req -newkey rsa:2048 -days 3600 -nodes -subj "${OPENSSL_SERVER}" -keyout server-key.pem -out server-req.pem -openssl rsa -in server-key.pem -out server-key.pem -openssl x509 -req -in server-req.pem -days 3600 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem -openssl req -newkey rsa:2048 -days 3600 -nodes -subj "${OPENSSL_CLIENT}" -keyout client-key.pem -out client-req.pem -openssl rsa -in client-key.pem -out client-key.pem -openssl x509 -req -in client-req.pem -days 3600 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem -openssl verify -CAfile ca.pem server-cert.pem client-cert.pem \ No newline at end of file diff --git a/docker/prod/standalone/selfsigned/Dockerfile b/docker/prod/standalone/selfsigned/Dockerfile new file mode 100644 index 00000000..f51d38b4 --- /dev/null +++ b/docker/prod/standalone/selfsigned/Dockerfile @@ -0,0 +1,48 @@ +# Clone git repository form specified tag +FROM alpine/git + +ARG GIT_TAG + +WORKDIR /sebserver +RUN if [ "x$arg" = "x" ] ; \ + then git clone --depth 1 https://github.com/SafeExamBrowser/seb-server.git ; \ + else git clone -b "$GIT_TAG" --depth 1 https://github.com/SafeExamBrowser/seb-server.git ; fi + +# Build with maven (skip tests) +FROM maven:latest + +ARG SEBSERVER_VERSION + +WORKDIR /sebserver +COPY --from=0 /sebserver/seb-server /sebserver +RUN mvn clean install -DskipTests + +FROM openjdk:11-jre-stretch + +ARG SEBSERVER_VERSION + +WORKDIR /sebserver +COPY --from=1 /sebserver/target/seb-server-"$SEBSERVER_VERSION".jar /sebserver + +ENTRYPOINT ["sh", "-c"] + +ENV SERVER_ADDRESS=0.0.0.0 +ENV SERVER_PORT=80 +ENV DBSERVER_ADDRESS=localhost +ENV DBSERVER_PORT=3306 +ENV KEYSTORE_PWD= + +CMD java \ + -Dfile.encoding=UTF-8 \ + -Djavax.net.ssl.keyStore=seb-server-keystore.pkcs12 \ + -Djavax.net.ssl.keyStorePassword="${KEYSTORE_PWD}" \ + -Djavax.net.ssl.trustStore=seb-server-truststore.pkcs12 \ + -Djavax.net.ssl.trustStorePassword="${KEYSTORE_PWD}" \ + -jar seb-server-"${SEBSERVER_VERSION}".jar \ + --spring.config.location=classpath:/config/,file:/sebserver/ \ + --server.address="${SERVER_ADDRESS}" \ + --spring.profiles.active=dev \ + --datastore.mariadb.server.address="${DBSERVER_ADDRESS}" \ + --datastore.mariadb.server.port="${DBSERVER_PORT}" + +EXPOSE $PORT \ No newline at end of file diff --git a/docker/prod/standalone/selfsigned/docker-compose.yml b/docker/prod/standalone/selfsigned/docker-compose.yml new file mode 100644 index 00000000..3a9010da --- /dev/null +++ b/docker/prod/standalone/selfsigned/docker-compose.yml @@ -0,0 +1,53 @@ +version: '3' +services: + selfsigned: + build: + context: ./gencerts + dockerfile: Dockerfile + container_name: gencerts + volumes: + - ./certs:/certs + environment: + - KEYSTORE_PWD=[TO SET] + + mariadb: + image: "mariadb/server:10.3" + container_name: seb-server-mariadb + volumes: + - .:/etc/mysql/conf.d + - ./certs:/etc/mysql/certs + - seb-server-mariadb-data:/var/lib/mysql + environment: + - MYSQL_ROOT_PASSWORD=[TO SET] + ports: + - 3306:3306 + networks: + - seb-server-network + depends_on: + - "selfsigned" + + seb-server: + build: + context: . + args: + - GIT_TAG=v0.4.0-beta + - SEBSERVER_VERSION=0.4.0-SNAPSHOT + container_name: seb-server + environment: + - SERVER_ADDRESS + - SERVER_PORT + - DBSERVER_ADDRESS + - DBSERVER_PORT + - KEYSTORE_PWD=[TO SET] + ports: + - 80:80 + networks: + - seb-server-network + depends_on: + - "mariadb" + +networks: + seb-server-network: + +volumes: + seb-server-mariadb-data: \ No newline at end of file diff --git a/docker/prod/standalone/selfsigned/gencerts/Dockerfile b/docker/prod/standalone/selfsigned/gencerts/Dockerfile new file mode 100644 index 00000000..a2ef1498 --- /dev/null +++ b/docker/prod/standalone/selfsigned/gencerts/Dockerfile @@ -0,0 +1,30 @@ +FROM openjdk:11-jre-stretch + +RUN apt-get update && apt-get install -y openssl + +ENV KEYSTORE_PWD= +ENV SERVER_CN="localhost" +ENV CLIENT_CN="localhost" +ENV OPENSSL_SUBJ="/C=CH/ST=Zuerich/L=Zuerich" +ENV OPENSSL_CA="${OPENSSL_SUBJ}/CN=demo-CA" +ENV OPENSSL_SERVER="${OPENSSL_SUBJ}/CN=${SERVER_CN}" +ENV OPENSSL_CLIENT="${OPENSSL_SUBJ}/CN=${CLIENT_CN}" + +VOLUME /certs + +WORKDIR /certs + +# This works on windows +CMD openssl genrsa -out ca-key.pem 2048 \ + && openssl req -new -x509 -key ca-key.pem -nodes -days 3600 -subj "${OPENSSL_CA}" -out ca.pem \ + && openssl req -newkey rsa:2048 -days 3600 -nodes -subj "${OPENSSL_SERVER}" -keyout server-key.pem -out server-req.pem \ + && openssl rsa -in server-key.pem -out server-key.pem \ + && openssl x509 -req -in server-req.pem -days 3600 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem \ + && openssl req -newkey rsa:2048 -days 3600 -nodes -subj "${OPENSSL_CLIENT}" -keyout client-key.pem -out client-req.pem \ + && openssl rsa -in client-key.pem -out client-key.pem \ + && openssl x509 -req -in client-req.pem -days 3600 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem \ + && openssl verify -CAfile ca.pem server-cert.pem client-cert.pem \ + && openssl x509 -in ca.pem -inform pem -out ca.der -outform der \ + && openssl pkcs12 -export -out client-cert.pkcs12 -in client-cert.pem -inkey client-key.pem -passout pass:"${KEYSTORE_PWD}" \ + && keytool -importkeystore -destkeystore seb-server-keystore.pkcs12 -deststorepass "${KEYSTORE_PWD}" -srckeystore client-cert.pkcs12 -srcstoretype PKCS12 -srcstorepass "${KEYSTORE_PWD}" \ + && keytool -import -file ca.pem -keystore seb-server-truststore.pkcs12 -storepass "${KEYSTORE_PWD}" -srcstoretype PKCS12 -noprompt \ No newline at end of file diff --git a/docker/prod/standalone/selfsigned/mariadb.cnf b/docker/prod/standalone/selfsigned/mariadb.cnf new file mode 100644 index 00000000..99df9666 --- /dev/null +++ b/docker/prod/standalone/selfsigned/mariadb.cnf @@ -0,0 +1,9 @@ +[mysqld] +ssl-ca=/etc/mysql/certs/ca.pem +ssl-cert=/etc/mysql/certs/server-cert.pem +ssl-key=/etc/mysql/certs/server-key.pem + +[client] +ssl-ca=/etc/mysql/certs/ca.pem +ssl-cert=/etc/mysql/certs/client-cert.pem +ssl-key=/etc/mysql/certs/client-key.pem \ No newline at end of file diff --git a/pom.xml b/pom.xml index a025fe0d..1ac0ad9f 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ ch.ethz.seb seb-server - 0.4.0-SNAPSHOT + ${sebserver-version}-SNAPSHOT seb-server web-service for SEB maintenance and monitoring active SEB sessions @@ -18,6 +18,7 @@ jar + 0.4.0 UTF-8 UTF-8 diff --git a/src/main/java/ch/ethz/seb/sebserver/WebSecurityConfig.java b/src/main/java/ch/ethz/seb/sebserver/WebSecurityConfig.java index ea916d7d..7bf87fe1 100644 --- a/src/main/java/ch/ethz/seb/sebserver/WebSecurityConfig.java +++ b/src/main/java/ch/ethz/seb/sebserver/WebSecurityConfig.java @@ -20,6 +20,7 @@ import java.security.cert.CertificateException; import javax.net.ssl.SSLContext; import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang3.StringUtils; import org.apache.http.client.HttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.ssl.SSLContextBuilder; @@ -136,12 +137,6 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter implements E } /** A ClientHttpRequestFactory used in production with TSL SSL configuration. - * - * NOTE: - * environment property: sebserver.gui.truststore.pwd is expected to have the correct truststore password set - * environment property: sebserver.gui.truststore.type is expected to set to the correct type of truststore - * truststore.jks is expected to be on the classpath containing all trusted certificates for request - * to SSL secured SEB Server webservice * * @return ClientHttpRequestFactory with TLS / SSL configuration * @throws IOException @@ -158,8 +153,17 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter implements E log.info("Initialize with secure ClientHttpRequestFactory for production"); + final String truststoreFilePath = env + .getProperty("javax.net.ssl.trustStore", ""); + + if (StringUtils.isBlank(truststoreFilePath)) { + throw new IllegalArgumentException("Missing trust-store file path"); + } + + final File trustStoreFile = ResourceUtils.getFile("file:" + truststoreFilePath); + final char[] password = env - .getProperty("sebserver.gui.truststore.pwd", "") + .getProperty("javax.net.ssl.trustStorePassword", "") .toCharArray(); if (password.length < 3) { @@ -167,8 +171,6 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter implements E throw new IllegalArgumentException("Missing or incorrect trust-store password"); } - final File trustStoreFile = ResourceUtils.getFile("classpath:truststore.jks"); - final SSLContext sslContext = SSLContextBuilder .create() .loadTrustMaterial(trustStoreFile, password) diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/InstitutionalAuthenticationEntryPoint.java b/src/main/java/ch/ethz/seb/sebserver/gui/InstitutionalAuthenticationEntryPoint.java index 73b8afea..e3b018f0 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/InstitutionalAuthenticationEntryPoint.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/InstitutionalAuthenticationEntryPoint.java @@ -143,6 +143,12 @@ final class InstitutionalAuthenticationEntryPoint implements AuthenticationEntry return null; } + /** TODO this seems not to work as expected. Different Theme is only possible in RAP on different + * entry-points and since entry-points are statically defined within the RAPConficuration + * there is no possibility to apply them dynamically within an institution so far. + * + * @param institutionalEndpoint + * @return */ private boolean initInstitutionalBasedThemeEntryPoint(final String institutionalEndpoint) { try { final ApplicationContextImpl appContext = (ApplicationContextImpl) RWT.getApplicationContext(); diff --git a/src/main/resources/config/application-dev-ws.properties b/src/main/resources/config/application-dev-ws.properties index 25053241..f5a7a2a8 100644 --- a/src/main/resources/config/application-dev-ws.properties +++ b/src/main/resources/config/application-dev-ws.properties @@ -7,7 +7,7 @@ logging.file=log/sebserver.log # data source configuration spring.datasource.initialize=true spring.datasource.initialization-mode=always -spring.datasource.url=jdbc:mariadb://localhost:6603/SEBServer?useSSL=false&createDatabaseIfNotExist=true +spring.datasource.url=jdbc:mariadb://localhost:6603/SEBServer?createDatabaseIfNotExist=true&verifyServerCertificate=true&useSSL=true&requireSSL=true spring.datasource.driver-class-name=org.mariadb.jdbc.Driver spring.datasource.platform=dev spring.datasource.hikari.max-lifetime=600000 diff --git a/src/main/resources/data-prod.sql b/src/main/resources/data-prod.sql new file mode 100644 index 00000000..d8bbd9dc --- /dev/null +++ b/src/main/resources/data-prod.sql @@ -0,0 +1,14 @@ +INSERT IGNORE INTO institution VALUES + (1, 'SEB Server [ROOT]', null, null, null, 1) + ; + +INSERT IGNORE INTO user VALUES + (1, 1, 'super-admin', 'super-admin', 'super-admin', '$2a$08$c2GKYEYoUVXH1Yb8GXVXVu66ltPvbZgLMcVSXRH.LgZNF/YeaYB8m', 'super-admin@nomail.nomail', 'en', 'UTC', 1) + ; + +INSERT IGNORE INTO user_role VALUES + (1, 1, 'SEB_SERVER_ADMIN'), + (2, 1, 'INSTITUTIONAL_ADMIN'), + (3, 1, 'EXAM_ADMIN'), + (4, 1, 'EXAM_SUPPORTER') + ; \ No newline at end of file diff --git a/src/main/resources/schema-prod.sql b/src/main/resources/schema-prod.sql new file mode 100644 index 00000000..cc2befb9 --- /dev/null +++ b/src/main/resources/schema-prod.sql @@ -0,0 +1,474 @@ +-- MySQL Script generated by MySQL Workbench +-- Mon Jun 24 10:23:04 2019 +-- Model: New Model Version: 1.0 +-- MySQL Workbench Forward Engineering + +SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; +SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; +SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES'; + +-- ----------------------------------------------------- +-- Schema SEBServer +-- ----------------------------------------------------- +CREATE SCHEMA IF NOT EXISTS `SEBServer` DEFAULT CHARACTER SET utf8mb4 ; +USE `SEBServer` ; + +-- ----------------------------------------------------- +-- Table `institution` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `institution` ( + `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + `name` VARCHAR(255) NOT NULL, + `url_suffix` VARCHAR(45) NULL, + `logo_image` MEDIUMTEXT NULL, + `theme_name` VARCHAR(45) NULL, + `active` INT(1) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE INDEX `name_UNIQUE` (`name` ASC)) +; + + +-- ----------------------------------------------------- +-- Table `lms_setup` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `lms_setup` ( + `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + `institution_id` BIGINT UNSIGNED NOT NULL, + `name` VARCHAR(255) NOT NULL, + `lms_type` VARCHAR(45) NOT NULL, + `lms_url` VARCHAR(255) NULL, + `lms_clientname` VARCHAR(4000) NULL, + `lms_clientsecret` VARCHAR(4000) NULL, + `lms_rest_api_token` VARCHAR(4000) NULL, + `active` INT(1) NOT NULL, + PRIMARY KEY (`id`), + INDEX `setupInstitutionRef_idx` (`institution_id` ASC), + CONSTRAINT `setupInstitutionRef` + FOREIGN KEY (`institution_id`) + REFERENCES `institution` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +; + + +-- ----------------------------------------------------- +-- Table `exam` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `exam` ( + `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + `institution_id` BIGINT UNSIGNED NOT NULL, + `lms_setup_id` BIGINT UNSIGNED NOT NULL, + `external_id` VARCHAR(255) NOT NULL, + `owner` VARCHAR(255) NOT NULL, + `supporter` VARCHAR(4000) NULL COMMENT 'comma separated list of user_uuid', + `type` VARCHAR(45) NOT NULL, + `quit_password` VARCHAR(4000) NULL, + `browser_keys` VARCHAR(4000) NULL, + `active` INT(1) NOT NULL, + PRIMARY KEY (`id`), + INDEX `lms_setup_key_idx` (`lms_setup_id` ASC), + INDEX `institution_key_idx` (`institution_id` ASC), + CONSTRAINT `examLmsSetupRef` + FOREIGN KEY (`lms_setup_id`) + REFERENCES `lms_setup` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `examInstitutionRef` + FOREIGN KEY (`institution_id`) + REFERENCES `institution` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +; + +-- ----------------------------------------------------- +-- Table `client_connection` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `client_connection` ( + `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + `institution_id` BIGINT UNSIGNED NOT NULL, + `exam_id` BIGINT UNSIGNED NULL, + `status` VARCHAR(45) NOT NULL, + `connection_token` VARCHAR(255) NOT NULL, + `exam_user_session_identifer` VARCHAR(255) NULL, + `client_address` VARCHAR(45) NOT NULL, + `virtual_client_address` VARCHAR(45) NULL, + PRIMARY KEY (`id`), + INDEX `connection_exam_ref_idx` (`exam_id` ASC), + INDEX `clientConnectionInstitutionRef_idx` (`institution_id` ASC), + CONSTRAINT `clientConnectionExamRef` + FOREIGN KEY (`exam_id`) + REFERENCES `exam` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `clientConnectionInstitutionRef` + FOREIGN KEY (`institution_id`) + REFERENCES `institution` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION); + + +-- ----------------------------------------------------- +-- Table `client_event` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `client_event` ( + `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + `connection_id` BIGINT UNSIGNED NOT NULL, + `type` INT(2) UNSIGNED NOT NULL, + `client_time` BIGINT UNSIGNED NOT NULL, + `server_time` BIGINT NOT NULL, + `numeric_value` DECIMAL(10,4) NULL, + `text` VARCHAR(512) NULL, + PRIMARY KEY (`id`), + INDEX `eventConnectionRef_idx` (`connection_id` ASC), + CONSTRAINT `eventConnectionRef` + FOREIGN KEY (`connection_id`) + REFERENCES `client_connection` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +; + + +-- ----------------------------------------------------- +-- Table `indicator` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `indicator` ( + `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + `exam_id` BIGINT UNSIGNED NOT NULL, + `type` VARCHAR(45) NOT NULL, + `name` VARCHAR(45) NOT NULL, + `color` VARCHAR(45) NULL, + INDEX `indicator_exam_idx` (`exam_id` ASC), + PRIMARY KEY (`id`), + CONSTRAINT `exam_ref` + FOREIGN KEY (`exam_id`) + REFERENCES `exam` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +; + + +-- ----------------------------------------------------- +-- Table `configuration_node` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `configuration_node` ( + `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + `institution_id` BIGINT UNSIGNED NOT NULL, + `template_id` BIGINT UNSIGNED NULL, + `owner` VARCHAR(255) NOT NULL, + `name` VARCHAR(255) NOT NULL, + `description` VARCHAR(4000) NULL, + `type` VARCHAR(45) NULL, + `status` VARCHAR(45) NOT NULL, + PRIMARY KEY (`id`), + INDEX `configurationInstitutionRef_idx` (`institution_id` ASC), + CONSTRAINT `configurationInstitutionRef` + FOREIGN KEY (`institution_id`) + REFERENCES `institution` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +; + + +-- ----------------------------------------------------- +-- Table `configuration` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `configuration` ( + `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + `institution_id` BIGINT UNSIGNED NOT NULL, + `configuration_node_id` BIGINT UNSIGNED NOT NULL, + `version` VARCHAR(255) NULL, + `version_date` DATETIME NULL, + `followup` INT(1) NOT NULL, + PRIMARY KEY (`id`), + INDEX `configurationNodeRef_idx` (`configuration_node_id` ASC), + INDEX `config_institution_ref_idx` (`institution_id` ASC), + CONSTRAINT `configuration_node_ref` + FOREIGN KEY (`configuration_node_id`) + REFERENCES `configuration_node` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `config_institution_ref` + FOREIGN KEY (`institution_id`) + REFERENCES `institution` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +; + + +-- ----------------------------------------------------- +-- Table `configuration_attribute` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `configuration_attribute` ( + `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + `name` VARCHAR(45) NOT NULL, + `type` VARCHAR(45) NOT NULL, + `parent_id` BIGINT UNSIGNED NULL, + `resources` VARCHAR(255) NULL, + `validator` VARCHAR(45) NULL, + `dependencies` VARCHAR(255) NULL, + `default_value` VARCHAR(255) NULL, + PRIMARY KEY (`id`), + INDEX `parent_ref_idx` (`parent_id` ASC), + CONSTRAINT `parent_ref` + FOREIGN KEY (`parent_id`) + REFERENCES `configuration_attribute` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +; + + +-- ----------------------------------------------------- +-- Table `configuration_value` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `configuration_value` ( + `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + `institution_id` BIGINT UNSIGNED NOT NULL, + `configuration_id` BIGINT UNSIGNED NOT NULL, + `configuration_attribute_id` BIGINT UNSIGNED NOT NULL, + `list_index` INT NOT NULL DEFAULT 0, + `value` VARCHAR(16000) NULL, + PRIMARY KEY (`id`), + INDEX `configuration_value_ref_idx` (`configuration_id` ASC), + INDEX `configuration_attribute_ref_idx` (`configuration_attribute_id` ASC), + INDEX `configuration_value_institution_ref_idx` (`institution_id` ASC), + CONSTRAINT `configuration_ref` + FOREIGN KEY (`configuration_id`) + REFERENCES `configuration` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `configuration_value_attribute_ref` + FOREIGN KEY (`configuration_attribute_id`) + REFERENCES `configuration_attribute` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `configuration_value_institution_ref` + FOREIGN KEY (`institution_id`) + REFERENCES `institution` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +; + + +-- ----------------------------------------------------- +-- Table `view` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `view` ( + `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + `name` VARCHAR(255) NULL, + `columns` INT NOT NULL, + `position` INT NOT NULL, + PRIMARY KEY (`id`)) +; + + +-- ----------------------------------------------------- +-- Table `orientation` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `orientation` ( + `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + `config_attribute_id` BIGINT UNSIGNED NOT NULL, + `template_id` BIGINT UNSIGNED NULL, + `view_id` BIGINT UNSIGNED NOT NULL, + `group_id` VARCHAR(45) NULL, + `x_position` INT UNSIGNED NOT NULL DEFAULT 0, + `y_position` INT UNSIGNED NOT NULL DEFAULT 0, + `width` INT UNSIGNED NULL, + `height` INT UNSIGNED NULL, + `title` VARCHAR(45) NULL, + PRIMARY KEY (`id`), + INDEX `config_attribute_orientation_rev_idx` (`config_attribute_id` ASC), + INDEX `orientation_view_ref_idx` (`view_id` ASC), + CONSTRAINT `config_attribute_orientation_ref` + FOREIGN KEY (`config_attribute_id`) + REFERENCES `configuration_attribute` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `orientation_view_ref` + FOREIGN KEY (`view_id`) + REFERENCES `view` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +; + + +-- ----------------------------------------------------- +-- Table `exam_configuration_map` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `exam_configuration_map` ( + `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + `institution_id` BIGINT UNSIGNED NOT NULL, + `exam_id` BIGINT UNSIGNED NOT NULL, + `configuration_node_id` BIGINT UNSIGNED NOT NULL, + `user_names` VARCHAR(4000) NULL, + `encrypt_secret` VARCHAR(255) NULL, + PRIMARY KEY (`id`), + INDEX `exam_ref_idx` (`exam_id` ASC), + INDEX `configuration_map_ref_idx` (`configuration_node_id` ASC), + INDEX `exam_config_institution_ref_idx` (`institution_id` ASC), + CONSTRAINT `exam_map_ref` + FOREIGN KEY (`exam_id`) + REFERENCES `exam` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `configuration_map_ref` + FOREIGN KEY (`configuration_node_id`) + REFERENCES `configuration_node` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `exam_config_institution_ref` + FOREIGN KEY (`institution_id`) + REFERENCES `institution` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +; + + +-- ----------------------------------------------------- +-- Table `user` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `user` ( + `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + `institution_id` BIGINT UNSIGNED NOT NULL, + `uuid` VARCHAR(255) NOT NULL, + `name` VARCHAR(255) NOT NULL, + `username` VARCHAR(255) NOT NULL, + `password` VARCHAR(255) NOT NULL, + `email` VARCHAR(255) NULL, + `language` VARCHAR(45) NOT NULL, + `timeZone` VARCHAR(45) NOT NULL, + `active` INT(1) NOT NULL, + PRIMARY KEY (`id`), + INDEX `institutionRef_idx` (`institution_id` ASC), + CONSTRAINT `userInstitutionRef` + FOREIGN KEY (`institution_id`) + REFERENCES `institution` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +; + + +-- ----------------------------------------------------- +-- Table `user_role` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `user_role` ( + `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + `user_id` BIGINT UNSIGNED NOT NULL, + `role_name` VARCHAR(45) NOT NULL, + PRIMARY KEY (`id`), + INDEX `user_ref_idx` (`user_id` ASC), + CONSTRAINT `user_ref` + FOREIGN KEY (`user_id`) + REFERENCES `user` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +; + + +-- ----------------------------------------------------- +-- Table `oauth_access_token` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `oauth_access_token` ( + `token_id` VARCHAR(255) NULL, + `token` BLOB NULL, + `authentication_id` VARCHAR(255) NULL, + `user_name` VARCHAR(255) NULL, + `client_id` VARCHAR(255) NULL, + `authentication` BLOB NULL, + `refresh_token` VARCHAR(255) NULL, + UNIQUE INDEX `authentication_id_UNIQUE` (`authentication_id` ASC)) +; + + + +-- ----------------------------------------------------- +-- Table `oauth_refresh_token` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `oauth_refresh_token` ( + `token_id` VARCHAR(255) NULL, + `token` BLOB NULL, + `authentication` BLOB NULL) +; + + +-- ----------------------------------------------------- +-- Table `threshold` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `threshold` ( + `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + `indicator_id` BIGINT UNSIGNED NOT NULL, + `value` DECIMAL(10,4) NOT NULL, + `color` VARCHAR(45) NULL, + PRIMARY KEY (`id`), + INDEX `indicator_threshold_id_idx` (`indicator_id` ASC), + CONSTRAINT `indicator_threshold_id` + FOREIGN KEY (`indicator_id`) + REFERENCES `indicator` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +; + + +-- ----------------------------------------------------- +-- Table `user_activity_log` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `user_activity_log` ( + `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + `user_uuid` VARCHAR(255) NOT NULL, + `timestamp` BIGINT NOT NULL, + `activity_type` VARCHAR(45) NOT NULL, + `entity_type` VARCHAR(45) NOT NULL, + `entity_id` VARCHAR(255) NOT NULL, + `message` VARCHAR(4000) NULL, + PRIMARY KEY (`id`)) +; + + +-- ----------------------------------------------------- +-- Table `additional_attributes` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `additional_attributes` ( + `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + `entity_type` VARCHAR(45) NOT NULL, + `entity_id` BIGINT UNSIGNED NOT NULL, + `name` VARCHAR(255) NOT NULL, + `value` VARCHAR(4000) NULL, + PRIMARY KEY (`id`)) +ENGINE = InnoDB; + + +-- ----------------------------------------------------- +-- Table `seb_client_configuration` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `seb_client_configuration` ( + `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + `institution_id` BIGINT UNSIGNED NOT NULL, + `name` VARCHAR(255) NOT NULL, + `date` DATETIME NOT NULL, + `client_name` VARCHAR(4000) NOT NULL, + `client_secret` VARCHAR(4000) NOT NULL, + `encrypt_secret` VARCHAR(255) NULL, + `active` INT(1) NOT NULL, + PRIMARY KEY (`id`), + INDEX `sebClientCredentialsInstitutionRef_idx` (`institution_id` ASC), + CONSTRAINT `sebClientConfigInstitutionRef` + FOREIGN KEY (`institution_id`) + REFERENCES `institution` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +; + + +-- ----------------------------------------------------- +-- Table `webservice_server_info` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `webservice_server_info` ( + `id` BIGINT UNSIGNED NOT NULL, + `uuid` VARCHAR(255) NOT NULL, + `service_address` VARCHAR(255) NOT NULL, + PRIMARY KEY (`id`)) +; + + +SET SQL_MODE=@OLD_SQL_MODE; +SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; +SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;