Merge branch 'tibor' into 'master'
Tibor See merge request bossanyit/aitrainer_server!1
This commit is contained in:
commit
6b558a0173
32
.gitignore
vendored
Normal file
32
.gitignore
vendored
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
HELP.md
|
||||||
|
.gradle
|
||||||
|
build/
|
||||||
|
!gradle/wrapper/gradle-wrapper.jar
|
||||||
|
!**/src/main/**
|
||||||
|
!**/src/test/**
|
||||||
|
|
||||||
|
### STS ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
out/
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
66
.gitlab-ci.yml
Normal file
66
.gitlab-ci.yml
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- build
|
||||||
|
- prepare
|
||||||
|
- test
|
||||||
|
- deploy
|
||||||
|
|
||||||
|
variables:
|
||||||
|
# Configure mysql environment variables (https://hub.docker.com/_/mysql/)
|
||||||
|
MYSQL_DATABASE: "aitrainer"
|
||||||
|
MYSQL_ROOT_PASSWORD: "andio2009"
|
||||||
|
MYSQL_USER: "aitrainer"
|
||||||
|
MYSQL_PASSWORD: "andio2009"
|
||||||
|
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- echo `pwd` # debug
|
||||||
|
- echo "$CI_BUILD_NAME, $CI_BUILD_REF_NAME $CI_BUILD_STAGE" # debug
|
||||||
|
- export GRADLE_USER_HOME=`pwd`/.gradle
|
||||||
|
|
||||||
|
cache:
|
||||||
|
paths:
|
||||||
|
- .gradle/wrapper
|
||||||
|
- .gradle/caches
|
||||||
|
|
||||||
|
build:
|
||||||
|
stage: build
|
||||||
|
image: openjdk:latest
|
||||||
|
script:
|
||||||
|
- ./gradlew assemble
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- build/libs/*.jar
|
||||||
|
expire_in: 1 week
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
|
||||||
|
connect:
|
||||||
|
stage: prepare
|
||||||
|
image: mysql:latest
|
||||||
|
script:
|
||||||
|
- apt-get update && apt-get --assume-yes install mysql-client
|
||||||
|
- mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql -e "use $MYSQL_DATABASE; show tables;"
|
||||||
|
- mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql -e "use $MYSQL_DATABASE; DROP table if exists customer; DROP table if exists exercises; DROP table if exists exercise_type; DROP table if exists exercise_ages;"
|
||||||
|
- mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql < "data/db/install.sql" #first time
|
||||||
|
|
||||||
|
test:
|
||||||
|
stage: test
|
||||||
|
image: openjdk:latest
|
||||||
|
script:
|
||||||
|
- export spring_profiles_active=test
|
||||||
|
- ./gradlew check
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
stage: deploy
|
||||||
|
image: mysql:latest
|
||||||
|
script:
|
||||||
|
- apt-get update && apt-get --assume-yes install sshpass
|
||||||
|
- chmod +x ci-cd/deploy.sh
|
||||||
|
- ci-cd/deploy.sh
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
|
||||||
|
after_script:
|
||||||
|
- echo "End CI"
|
1
.gitlab-runner-register
Normal file
1
.gitlab-runner-register
Normal file
@ -0,0 +1 @@
|
|||||||
|
docker run --rm -t -i -v /srv/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner register
|
58
build.gradle.kts
Normal file
58
build.gradle.kts
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
|
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id("org.springframework.boot") version "2.3.0.RELEASE"
|
||||||
|
id("io.spring.dependency-management") version "1.0.9.RELEASE"
|
||||||
|
kotlin("jvm") version "1.3.72"
|
||||||
|
kotlin("plugin.spring") version "1.3.72"
|
||||||
|
kotlin("plugin.jpa") version "1.3.72"
|
||||||
|
kotlin("plugin.serialization") version "1.3.70"
|
||||||
|
}
|
||||||
|
|
||||||
|
group = "com.aitrainer"
|
||||||
|
version = "0.0.5"
|
||||||
|
java.sourceCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter-web")
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter-aop")
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter-validation")
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter-security")
|
||||||
|
implementation("org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.3.0.RELEASE")
|
||||||
|
implementation("org.springframework.security.oauth:spring-security-oauth2:2.5.0.RELEASE")
|
||||||
|
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
|
||||||
|
implementation("org.jetbrains.kotlin:kotlin-reflect")
|
||||||
|
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
|
||||||
|
implementation("org.apache.logging.log4j:log4j-core:2.13.3")
|
||||||
|
implementation("org.apache.logging.log4j:log4j-api:2.13.3")
|
||||||
|
implementation("org.slf4j:slf4j-api:1.7.30")
|
||||||
|
implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.20.0") // JVM dependency
|
||||||
|
implementation("io.jsonwebtoken:jjwt:0.9.1")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
runtimeOnly("mysql:mysql-connector-java")
|
||||||
|
testImplementation("org.springframework.boot:spring-boot-starter-test") {
|
||||||
|
exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
|
||||||
|
}
|
||||||
|
testImplementation("junit:junit:4.13")
|
||||||
|
testImplementation("org.jetbrains.kotlin:kotlin-test-junit5:1.3.72")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<Test> {
|
||||||
|
useJUnitPlatform()
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<KotlinCompile> {
|
||||||
|
kotlinOptions {
|
||||||
|
freeCompilerArgs = listOf("-Xjsr305=strict")
|
||||||
|
jvmTarget = "1.8"
|
||||||
|
}
|
||||||
|
}
|
1
ci-cd/.ssh/.scp
Normal file
1
ci-cd/.ssh/.scp
Normal file
@ -0,0 +1 @@
|
|||||||
|
tbi6012AndiBossanyi
|
52
ci-cd/config.toml
Normal file
52
ci-cd/config.toml
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
concurrent = 4
|
||||||
|
log_level = "warning"
|
||||||
|
|
||||||
|
[session_server]
|
||||||
|
listen_address = "0.0.0.0:8093" # listen on all available interfaces on port 8093
|
||||||
|
advertise_address = "andio.club:8093"
|
||||||
|
session_timeout = 1800
|
||||||
|
|
||||||
|
[[runners]]
|
||||||
|
name = "aitraner-server-docker"
|
||||||
|
url = "https://andio.club"
|
||||||
|
token = "R_-WrxvRXkP6HuU95dEs"
|
||||||
|
limit = 0
|
||||||
|
executor = "shell"
|
||||||
|
builds_dir = "/home/bosi/build"
|
||||||
|
shell = "bash"
|
||||||
|
environment = ["ENV=value", "LC_ALL=en_US.UTF-8"]
|
||||||
|
clone_url = "http://localhost"
|
||||||
|
|
||||||
|
[runners.docker]
|
||||||
|
host = ""
|
||||||
|
hostname = ""
|
||||||
|
tls_cert_path = ""
|
||||||
|
image = "docker-runner"
|
||||||
|
memory = "128m"
|
||||||
|
memory_swap = "256m"
|
||||||
|
memory_reservation = "64m"
|
||||||
|
oom_kill_disable = false
|
||||||
|
cpuset_cpus = "0,1"
|
||||||
|
cpus = "2"
|
||||||
|
dns = ["8.8.8.8"]
|
||||||
|
dns_search = [""]
|
||||||
|
privileged = false
|
||||||
|
userns_mode = "host"
|
||||||
|
cap_add = ["NET_ADMIN"]
|
||||||
|
cap_drop = ["DAC_OVERRIDE"]
|
||||||
|
devices = ["/dev/net/tun"]
|
||||||
|
disable_cache = false
|
||||||
|
wait_for_services_timeout = 30
|
||||||
|
cache_dir = ""
|
||||||
|
volumes = ["/data", "/home/project/cache"]
|
||||||
|
extra_hosts = ["127.0.0.1"]
|
||||||
|
shm_size = 300000
|
||||||
|
volumes_from = ["storage_container:ro"]
|
||||||
|
links = ["mysql_container:mysql"]
|
||||||
|
allowed_images = ["ruby:*", "python:*", "php:*"]
|
||||||
|
allowed_services = ["mysql"]
|
||||||
|
[[runners.docker.services]]
|
||||||
|
name = "mysql"
|
||||||
|
alias = "db"
|
||||||
|
[runners.docker.sysctls]
|
||||||
|
"net.ipv4.ip_forward" = "1"
|
1
ci-cd/deploy.sh
Normal file
1
ci-cd/deploy.sh
Normal file
@ -0,0 +1 @@
|
|||||||
|
sshpass -f /ci-cd/.ssh/.scp scp -p 6622 build/libs/aitrainer_server-0.0.2.jar bosi@andio.shop:/home/bosi/aitrainer/deploy/aitrainer_server.jar
|
98
ci-cd/docker.development.yml
Normal file
98
ci-cd/docker.development.yml
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
version: '3.8'
|
||||||
|
services:
|
||||||
|
jira:
|
||||||
|
image: 'atlassian/jira-software:latest'
|
||||||
|
container_name: 'jira'
|
||||||
|
restart: 'always'
|
||||||
|
environment:
|
||||||
|
ATL_TOMCAT_PORT: 8082
|
||||||
|
ATL_TOMCAT_SCHEME: "https"
|
||||||
|
ATL_TOMCAT_SECURE: "true"
|
||||||
|
ATL_DB_DRIVER: "com.mysql.jdbc.Driver"
|
||||||
|
ATL_DB_TYPE: "mysql"
|
||||||
|
volumes:
|
||||||
|
- jiraVolume:/var/atlassian/application-data/jira
|
||||||
|
- db_data:/var/lib/mysql
|
||||||
|
ports:
|
||||||
|
- 8082:80
|
||||||
|
gitlab:
|
||||||
|
image: 'gitlab/gitlab-ce:latest'
|
||||||
|
container_name: 'gitlab'
|
||||||
|
restart: always
|
||||||
|
hostname: 'localhost'
|
||||||
|
environment:
|
||||||
|
GITLAB_OMNIBUS_CONFIG: |
|
||||||
|
external_url 'https://andio.club:443'
|
||||||
|
gitlab_rails['smtp_enable'] = true
|
||||||
|
gitlab_rails['smtp_address'] = "email-smtp.eu-west-1.amazonaws.com"
|
||||||
|
gitlab_rails['smtp_port'] = 587
|
||||||
|
gitlab_rails['smtp_user_name'] = "AKIAIWHHQDMPADT7ETHQ"
|
||||||
|
gitlab_rails['smtp_password'] = "AjCB8NA+61i/URp09gik0HHtbEuy48e4JXhuPaqGacFs"
|
||||||
|
gitlab_rails['smtp_domain'] = "andio.club"
|
||||||
|
gitlab_rails['smtp_authentication'] = "login"
|
||||||
|
gitlab_rails['smtp_enable_starttls_auto'] = true
|
||||||
|
gitlab_rails['smtp_openssl_verify_mode'] = 'peer'
|
||||||
|
# Add any other gitlab.rb configuration here, each on its own line
|
||||||
|
gitlab_rails['gitlab_shell_ssh_port'] = 6622
|
||||||
|
ports:
|
||||||
|
- '80:80'
|
||||||
|
- '443:443'
|
||||||
|
- '6622:22'
|
||||||
|
- '587:587'
|
||||||
|
volumes:
|
||||||
|
- '/srv/gitlab/config:/etc/gitlab'
|
||||||
|
- '/srv/gitlab/logs:/var/log/gitlab'
|
||||||
|
- '/srv/gitlab/data:/var/opt/gitlab'
|
||||||
|
mysql:
|
||||||
|
image: mysql:latest
|
||||||
|
volumes:
|
||||||
|
- db_data:/var/lib/mysql
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- 33061:33061
|
||||||
|
environment:
|
||||||
|
MYSQL_ROOT_PASSWORD: andio2009
|
||||||
|
MYSQL_DATABASE: aitrainer
|
||||||
|
MYSQL_USER: aitrainer
|
||||||
|
MYSQL_PASSWORD: andio2009
|
||||||
|
networks:
|
||||||
|
- bosi_default
|
||||||
|
phpmyadmin:
|
||||||
|
depends_on:
|
||||||
|
- mysql
|
||||||
|
image: phpmyadmin/phpmyadmin
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- '8081:80'
|
||||||
|
environment:
|
||||||
|
PMA_HOST: mysql
|
||||||
|
MYSQL_ROOT_PASSWORD: andio2009
|
||||||
|
networks:
|
||||||
|
- bosi_default
|
||||||
|
php:
|
||||||
|
image: php:7.2-fpm
|
||||||
|
volumes:
|
||||||
|
- php:/var/www/html
|
||||||
|
- ./php/php.ini:/usr/local/etc/php/php.ini
|
||||||
|
depends_on:
|
||||||
|
- mysql
|
||||||
|
gitlab-runner:
|
||||||
|
image: gitlab/gitlab-runner:latest
|
||||||
|
container_name: gitlab-runner
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
- bosi_default
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- /srv/gitlab-runner/config:/etc/gitlab-runner
|
||||||
|
secrets:
|
||||||
|
mysql_root_pwd:
|
||||||
|
file: /.sec/mysql_root_pwd
|
||||||
|
mysql_user_pwd:
|
||||||
|
file: /.sec/mysql_user_pwd
|
||||||
|
networks:
|
||||||
|
bosi_default:
|
||||||
|
volumes:
|
||||||
|
db_data:
|
||||||
|
php:
|
||||||
|
jiraVolume:
|
31
ci-cd/production-docker-compose.yml
Normal file
31
ci-cd/production-docker-compose.yml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
mysql:
|
||||||
|
image: mysql:latest
|
||||||
|
container_name: mysql
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
MYSQL_ROOT_PASSWORD: andio2009
|
||||||
|
MYSQL_DATABASE: aitrainer
|
||||||
|
MYSQL_USER: aitrainer
|
||||||
|
MYSQL_PASSWORD: andio2009
|
||||||
|
volumes:
|
||||||
|
- ./docker/db:/docker-entrypoint-initdb.d
|
||||||
|
ports:
|
||||||
|
- "33061:33061"
|
||||||
|
command: mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=localhost < "/home/bosi/aitrainer/data/install.sql"
|
||||||
|
|
||||||
|
java:
|
||||||
|
image: openjdk:latest
|
||||||
|
|
||||||
|
|
||||||
|
tomcat:
|
||||||
|
image: tomcat:latest
|
||||||
|
container_name: tomcat
|
||||||
|
volumes:
|
||||||
|
- ./docker/aitrainer_server.jar:/home/bosi/aitrainer/deploy/aitrainer_server.jar
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
depends_on:
|
||||||
|
- java
|
1
ci-cd/readme.md
Normal file
1
ci-cd/readme.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
jar file to deploy
|
631
data/config/docker-compose_cowmail.yml
Normal file
631
data/config/docker-compose_cowmail.yml
Normal file
@ -0,0 +1,631 @@
|
|||||||
|
version: '2.1'
|
||||||
|
services:
|
||||||
|
|
||||||
|
unbound-mailcow:
|
||||||
|
image: mailcow/unbound:1.12
|
||||||
|
environment:
|
||||||
|
- TZ=${TZ}
|
||||||
|
volumes:
|
||||||
|
- ./data/hooks/unbound:/hooks
|
||||||
|
- ./data/conf/unbound/unbound.conf:/etc/unbound/unbound.conf:ro
|
||||||
|
restart: always
|
||||||
|
tty: true
|
||||||
|
networks:
|
||||||
|
mailcow-network:
|
||||||
|
ipv4_address: ${IPV4_NETWORK:-172.22.1}.254
|
||||||
|
aliases:
|
||||||
|
- unbound
|
||||||
|
|
||||||
|
mysql-mailcow:
|
||||||
|
image: mariadb:10.3
|
||||||
|
depends_on:
|
||||||
|
- unbound-mailcow
|
||||||
|
stop_grace_period: 45s
|
||||||
|
volumes:
|
||||||
|
- mysql-vol-1:/var/lib/mysql/
|
||||||
|
- mysql-socket-vol-1:/var/run/mysqld/
|
||||||
|
- ./data/conf/mysql/:/etc/mysql/conf.d/:ro
|
||||||
|
environment:
|
||||||
|
- TZ=${TZ}
|
||||||
|
- MYSQL_ROOT_PASSWORD=${DBROOT}
|
||||||
|
- MYSQL_DATABASE=${DBNAME}
|
||||||
|
- MYSQL_USER=${DBUSER}
|
||||||
|
- MYSQL_PASSWORD=${DBPASS}
|
||||||
|
- MYSQL_INITDB_SKIP_TZINFO=1
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "${SQL_PORT:-127.0.0.1:13306}:3306"
|
||||||
|
networks:
|
||||||
|
mailcow-network:
|
||||||
|
aliases:
|
||||||
|
- mysql
|
||||||
|
|
||||||
|
redis-mailcow:
|
||||||
|
image: redis:5-alpine
|
||||||
|
volumes:
|
||||||
|
- redis-vol-1:/data/
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "${REDIS_PORT:-127.0.0.1:7654}:6379"
|
||||||
|
environment:
|
||||||
|
- TZ=${TZ}
|
||||||
|
networks:
|
||||||
|
mailcow-network:
|
||||||
|
ipv4_address: ${IPV4_NETWORK:-172.22.1}.249
|
||||||
|
aliases:
|
||||||
|
- redis
|
||||||
|
|
||||||
|
clamd-mailcow:
|
||||||
|
image: mailcow/clamd:1.36
|
||||||
|
restart: always
|
||||||
|
dns:
|
||||||
|
- ${IPV4_NETWORK:-172.22.1}.254
|
||||||
|
environment:
|
||||||
|
- TZ=${TZ}
|
||||||
|
- SKIP_CLAMD=${SKIP_CLAMD:-n}
|
||||||
|
volumes:
|
||||||
|
- ./data/conf/clamav/:/etc/clamav/
|
||||||
|
networks:
|
||||||
|
mailcow-network:
|
||||||
|
aliases:
|
||||||
|
- clamd
|
||||||
|
|
||||||
|
rspamd-mailcow:
|
||||||
|
image: mailcow/rspamd:1.68
|
||||||
|
stop_grace_period: 30s
|
||||||
|
depends_on:
|
||||||
|
- nginx-mailcow
|
||||||
|
- dovecot-mailcow
|
||||||
|
environment:
|
||||||
|
- TZ=${TZ}
|
||||||
|
- IPV4_NETWORK=${IPV4_NETWORK:-172.22.1}
|
||||||
|
- IPV6_NETWORK=${IPV6_NETWORK:-fd4d:6169:6c63:6f77::/64}
|
||||||
|
- REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
|
||||||
|
- REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
|
||||||
|
volumes:
|
||||||
|
- ./data/hooks/rspamd:/hooks
|
||||||
|
- ./data/conf/rspamd/custom/:/etc/rspamd/custom
|
||||||
|
- ./data/conf/rspamd/override.d/:/etc/rspamd/override.d
|
||||||
|
- ./data/conf/rspamd/local.d/:/etc/rspamd/local.d
|
||||||
|
- ./data/conf/rspamd/plugins.d/:/etc/rspamd/plugins.d
|
||||||
|
- ./data/conf/rspamd/lua/:/etc/rspamd/lua/:ro
|
||||||
|
- ./data/conf/rspamd/rspamd.conf.local:/etc/rspamd/rspamd.conf.local
|
||||||
|
- ./data/conf/rspamd/rspamd.conf.override:/etc/rspamd/rspamd.conf.override
|
||||||
|
- rspamd-vol-1:/var/lib/rspamd
|
||||||
|
restart: always
|
||||||
|
dns:
|
||||||
|
- ${IPV4_NETWORK:-172.22.1}.254
|
||||||
|
hostname: rspamd
|
||||||
|
networks:
|
||||||
|
mailcow-network:
|
||||||
|
aliases:
|
||||||
|
- rspamd
|
||||||
|
|
||||||
|
php-fpm-mailcow:
|
||||||
|
image: mailcow/phpfpm:1.63
|
||||||
|
command: "php-fpm -d date.timezone=${TZ} -d expose_php=0"
|
||||||
|
depends_on:
|
||||||
|
- redis-mailcow
|
||||||
|
volumes:
|
||||||
|
- ./data/hooks/phpfpm:/hooks
|
||||||
|
- ./data/web:/web:rw
|
||||||
|
- ./data/conf/rspamd/dynmaps:/dynmaps:ro
|
||||||
|
- ./data/conf/rspamd/custom/:/rspamd_custom_maps
|
||||||
|
- rspamd-vol-1:/var/lib/rspamd
|
||||||
|
- mysql-socket-vol-1:/var/run/mysqld/
|
||||||
|
- ./data/conf/sogo/:/etc/sogo/
|
||||||
|
- ./data/conf/rspamd/meta_exporter:/meta_exporter:ro
|
||||||
|
- ./data/conf/phpfpm/sogo-sso/:/etc/sogo-sso/
|
||||||
|
- ./data/conf/phpfpm/php-fpm.d/pools.conf:/usr/local/etc/php-fpm.d/z-pools.conf
|
||||||
|
- ./data/conf/phpfpm/php-conf.d/opcache-recommended.ini:/usr/local/etc/php/conf.d/opcache-recommended.ini
|
||||||
|
- ./data/conf/phpfpm/php-conf.d/upload.ini:/usr/local/etc/php/conf.d/upload.ini
|
||||||
|
- ./data/conf/phpfpm/php-conf.d/other.ini:/usr/local/etc/php/conf.d/zzz-other.ini
|
||||||
|
- ./data/conf/dovecot/global_sieve_before:/global_sieve/before
|
||||||
|
- ./data/conf/dovecot/global_sieve_after:/global_sieve/after
|
||||||
|
- ./data/assets/templates:/tpls
|
||||||
|
dns:
|
||||||
|
- ${IPV4_NETWORK:-172.22.1}.254
|
||||||
|
environment:
|
||||||
|
- REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
|
||||||
|
- REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
|
||||||
|
- LOG_LINES=${LOG_LINES:-9999}
|
||||||
|
- TZ=${TZ}
|
||||||
|
- DBNAME=${DBNAME}
|
||||||
|
- DBUSER=${DBUSER}
|
||||||
|
- DBPASS=${DBPASS}
|
||||||
|
- MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME}
|
||||||
|
- IMAP_PORT=${IMAP_PORT:-143}
|
||||||
|
- IMAPS_PORT=${IMAPS_PORT:-993}
|
||||||
|
- POP_PORT=${POP_PORT:-110}
|
||||||
|
- POPS_PORT=${POPS_PORT:-995}
|
||||||
|
- SIEVE_PORT=${SIEVE_PORT:-4190}
|
||||||
|
- SUBMISSION_PORT=${SUBMISSION_PORT:-587}
|
||||||
|
- SMTPS_PORT=${SMTPS_PORT:-465}
|
||||||
|
- SMTP_PORT=${SMTP_PORT:-25}
|
||||||
|
- API_KEY=${API_KEY:-invalid}
|
||||||
|
- API_KEY_READ_ONLY=${API_KEY_READ_ONLY:-invalid}
|
||||||
|
- API_ALLOW_FROM=${API_ALLOW_FROM:-invalid}
|
||||||
|
- COMPOSE_PROJECT_NAME=${COMPOSE_PROJECT_NAME:-mailcow-dockerized}
|
||||||
|
- SKIP_SOLR=${SKIP_SOLR:-y}
|
||||||
|
- SKIP_CLAMD=${SKIP_CLAMD:-n}
|
||||||
|
- SKIP_SOGO=${SKIP_SOGO:-n}
|
||||||
|
- ALLOW_ADMIN_EMAIL_LOGIN=${ALLOW_ADMIN_EMAIL_LOGIN:-n}
|
||||||
|
- MASTER=${MASTER:-y}
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
mailcow-network:
|
||||||
|
aliases:
|
||||||
|
- phpfpm
|
||||||
|
|
||||||
|
sogo-mailcow:
|
||||||
|
image: mailcow/sogo:1.74
|
||||||
|
environment:
|
||||||
|
- DBNAME=${DBNAME}
|
||||||
|
- DBUSER=${DBUSER}
|
||||||
|
- DBPASS=${DBPASS}
|
||||||
|
- TZ=${TZ}
|
||||||
|
- LOG_LINES=${LOG_LINES:-9999}
|
||||||
|
- MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME}
|
||||||
|
- ACL_ANYONE=${ACL_ANYONE:-disallow}
|
||||||
|
- ALLOW_ADMIN_EMAIL_LOGIN=${ALLOW_ADMIN_EMAIL_LOGIN:-n}
|
||||||
|
- IPV4_NETWORK=${IPV4_NETWORK:-172.22.1}
|
||||||
|
- SOGO_EXPIRE_SESSION=${SOGO_EXPIRE_SESSION:-480}
|
||||||
|
- SKIP_SOGO=${SKIP_SOGO:-n}
|
||||||
|
- MASTER=${MASTER:-y}
|
||||||
|
- REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
|
||||||
|
- REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
|
||||||
|
dns:
|
||||||
|
- ${IPV4_NETWORK:-172.22.1}.254
|
||||||
|
volumes:
|
||||||
|
- ./data/conf/sogo/:/etc/sogo/
|
||||||
|
- ./data/web/inc/init_db.inc.php:/init_db.inc.php
|
||||||
|
- ./data/conf/sogo/custom-sogo.js:/usr/lib/GNUstep/SOGo/WebServerResources/js/custom-sogo.js
|
||||||
|
- mysql-socket-vol-1:/var/run/mysqld/
|
||||||
|
- sogo-web-vol-1:/sogo_web
|
||||||
|
- sogo-userdata-backup-vol-1:/sogo_backup
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
mailcow-network:
|
||||||
|
ipv4_address: ${IPV4_NETWORK:-172.22.1}.248
|
||||||
|
aliases:
|
||||||
|
- sogo
|
||||||
|
|
||||||
|
dovecot-mailcow:
|
||||||
|
image: mailcow/dovecot:1.125
|
||||||
|
depends_on:
|
||||||
|
- mysql-mailcow
|
||||||
|
dns:
|
||||||
|
- ${IPV4_NETWORK:-172.22.1}.254
|
||||||
|
cap_add:
|
||||||
|
- NET_BIND_SERVICE
|
||||||
|
volumes:
|
||||||
|
- ./data/hooks/dovecot:/hooks
|
||||||
|
- ./data/conf/dovecot:/etc/dovecot
|
||||||
|
- ./data/assets/ssl:/etc/ssl/mail/:ro
|
||||||
|
- ./data/conf/sogo/:/etc/sogo/
|
||||||
|
- ./data/conf/phpfpm/sogo-sso/:/etc/phpfpm/
|
||||||
|
- vmail-vol-1:/var/vmail
|
||||||
|
- vmail-attachments-vol-1:/var/attachments
|
||||||
|
- crypt-vol-1:/mail_crypt/
|
||||||
|
- ./data/conf/rspamd/custom/:/etc/rspamd/custom
|
||||||
|
- ./data/assets/templates:/templates
|
||||||
|
- rspamd-vol-1:/var/lib/rspamd
|
||||||
|
- mysql-socket-vol-1:/var/run/mysqld/
|
||||||
|
environment:
|
||||||
|
- LOG_LINES=${LOG_LINES:-9999}
|
||||||
|
- DBNAME=${DBNAME}
|
||||||
|
- DBUSER=${DBUSER}
|
||||||
|
- DBPASS=${DBPASS}
|
||||||
|
- TZ=${TZ}
|
||||||
|
- MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME}
|
||||||
|
- IPV4_NETWORK=${IPV4_NETWORK:-172.22.1}
|
||||||
|
- ALLOW_ADMIN_EMAIL_LOGIN=${ALLOW_ADMIN_EMAIL_LOGIN:-n}
|
||||||
|
- MAILDIR_GC_TIME=${MAILDIR_GC_TIME:-1440}
|
||||||
|
- ACL_ANYONE=${ACL_ANYONE:-disallow}
|
||||||
|
- SKIP_SOLR=${SKIP_SOLR:-y}
|
||||||
|
- MAILDIR_SUB=${MAILDIR_SUB:-}
|
||||||
|
- MASTER=${MASTER:-y}
|
||||||
|
- REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
|
||||||
|
- REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
|
||||||
|
ports:
|
||||||
|
- "${DOVEADM_PORT:-127.0.0.1:19991}:12345"
|
||||||
|
- "${IMAP_PORT:-143}:143"
|
||||||
|
- "${IMAPS_PORT:-993}:993"
|
||||||
|
- "${POP_PORT:-110}:110"
|
||||||
|
- "${POPS_PORT:-995}:995"
|
||||||
|
- "${SIEVE_PORT:-4190}:4190"
|
||||||
|
restart: always
|
||||||
|
tty: true
|
||||||
|
ulimits:
|
||||||
|
nproc: 65535
|
||||||
|
nofile:
|
||||||
|
soft: 20000
|
||||||
|
hard: 40000
|
||||||
|
hostname: ${MAILCOW_HOSTNAME}
|
||||||
|
networks:
|
||||||
|
mailcow-network:
|
||||||
|
ipv4_address: ${IPV4_NETWORK:-172.22.1}.250
|
||||||
|
aliases:
|
||||||
|
- dovecot
|
||||||
|
|
||||||
|
postfix-mailcow:
|
||||||
|
image: mailcow/postfix:1.49
|
||||||
|
depends_on:
|
||||||
|
- mysql-mailcow
|
||||||
|
volumes:
|
||||||
|
- ./data/hooks/postfix:/hooks
|
||||||
|
- ./data/conf/postfix:/opt/postfix/conf
|
||||||
|
- ./data/assets/ssl:/etc/ssl/mail/:ro
|
||||||
|
- postfix-vol-1:/var/spool/postfix
|
||||||
|
- crypt-vol-1:/var/lib/zeyple
|
||||||
|
- rspamd-vol-1:/var/lib/rspamd
|
||||||
|
- mysql-socket-vol-1:/var/run/mysqld/
|
||||||
|
environment:
|
||||||
|
- LOG_LINES=${LOG_LINES:-9999}
|
||||||
|
- TZ=${TZ}
|
||||||
|
- DBNAME=${DBNAME}
|
||||||
|
- DBUSER=${DBUSER}
|
||||||
|
- DBPASS=${DBPASS}
|
||||||
|
- REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
|
||||||
|
- REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
|
||||||
|
cap_add:
|
||||||
|
- NET_BIND_SERVICE
|
||||||
|
ports:
|
||||||
|
- "${SMTP_PORT:-25}:25"
|
||||||
|
- "${SMTPS_PORT:-465}:465"
|
||||||
|
- "${SUBMISSION_PORT:-587}:587"
|
||||||
|
restart: always
|
||||||
|
dns:
|
||||||
|
- ${IPV4_NETWORK:-172.22.1}.254
|
||||||
|
hostname: ${MAILCOW_HOSTNAME}
|
||||||
|
networks:
|
||||||
|
mailcow-network:
|
||||||
|
aliases:
|
||||||
|
- postfix
|
||||||
|
|
||||||
|
memcached-mailcow:
|
||||||
|
image: memcached:alpine
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
- TZ=${TZ}
|
||||||
|
networks:
|
||||||
|
mailcow-network:
|
||||||
|
aliases:
|
||||||
|
- memcached
|
||||||
|
|
||||||
|
nginx-mailcow:
|
||||||
|
depends_on:
|
||||||
|
- sogo-mailcow
|
||||||
|
- php-fpm-mailcow
|
||||||
|
- redis-mailcow
|
||||||
|
image: nginx:mainline-alpine
|
||||||
|
dns:
|
||||||
|
- ${IPV4_NETWORK:-172.22.1}.254
|
||||||
|
command: /bin/sh -c "envsubst < /etc/nginx/conf.d/templates/listen_plain.template > /etc/nginx/conf.d/listen_plain.active &&
|
||||||
|
envsubst < /etc/nginx/conf.d/templates/listen_ssl.template > /etc/nginx/conf.d/listen_ssl.active &&
|
||||||
|
envsubst < /etc/nginx/conf.d/templates/server_name.template > /etc/nginx/conf.d/server_name.active &&
|
||||||
|
envsubst < /etc/nginx/conf.d/templates/sogo.template > /etc/nginx/conf.d/sogo.active &&
|
||||||
|
envsubst < /etc/nginx/conf.d/templates/sogo_eas.template > /etc/nginx/conf.d/sogo_eas.active &&
|
||||||
|
. /etc/nginx/conf.d/templates/sogo.auth_request.template.sh > /etc/nginx/conf.d/sogo_proxy_auth.active &&
|
||||||
|
. /etc/nginx/conf.d/templates/sites.template.sh > /etc/nginx/conf.d/sites.active &&
|
||||||
|
nginx -qt &&
|
||||||
|
until ping phpfpm -c1 > /dev/null; do sleep 1; done &&
|
||||||
|
until ping sogo -c1 > /dev/null; do sleep 1; done &&
|
||||||
|
until ping redis -c1 > /dev/null; do sleep 1; done &&
|
||||||
|
until ping rspamd -c1 > /dev/null; do sleep 1; done &&
|
||||||
|
exec nginx -g 'daemon off;'"
|
||||||
|
environment:
|
||||||
|
- HTTPS_PORT=${HTTPS_PORT:-443}
|
||||||
|
- HTTP_PORT=${HTTP_PORT:-80}
|
||||||
|
- MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME}
|
||||||
|
- IPV4_NETWORK=${IPV4_NETWORK:-172.22.1}
|
||||||
|
- TZ=${TZ}
|
||||||
|
- ALLOW_ADMIN_EMAIL_LOGIN=${ALLOW_ADMIN_EMAIL_LOGIN:-n}
|
||||||
|
volumes:
|
||||||
|
- ./data/web:/web:ro
|
||||||
|
- ./data/conf/rspamd/dynmaps:/dynmaps:ro
|
||||||
|
- ./data/assets/ssl/:/etc/ssl/mail/:ro
|
||||||
|
- ./data/conf/nginx/:/etc/nginx/conf.d/:rw
|
||||||
|
- ./data/conf/rspamd/meta_exporter:/meta_exporter:ro
|
||||||
|
- sogo-web-vol-1:/usr/lib/GNUstep/SOGo/
|
||||||
|
ports:
|
||||||
|
- "${HTTPS_BIND:-0.0.0.0}:${HTTPS_PORT:-443}:${HTTPS_PORT:-443}"
|
||||||
|
- "${HTTP_BIND:-0.0.0.0}:${HTTP_PORT:-80}:${HTTP_PORT:-80}"
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
mailcow-network:
|
||||||
|
aliases:
|
||||||
|
- nginx
|
||||||
|
|
||||||
|
acme-mailcow:
|
||||||
|
depends_on:
|
||||||
|
- nginx-mailcow
|
||||||
|
image: mailcow/acme:1.70
|
||||||
|
dns:
|
||||||
|
- ${IPV4_NETWORK:-172.22.1}.254
|
||||||
|
environment:
|
||||||
|
- LOG_LINES=${LOG_LINES:-9999}
|
||||||
|
- ADDITIONAL_SAN=${ADDITIONAL_SAN}
|
||||||
|
- MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME}
|
||||||
|
- DBNAME=${DBNAME}
|
||||||
|
- DBUSER=${DBUSER}
|
||||||
|
- DBPASS=${DBPASS}
|
||||||
|
- SKIP_LETS_ENCRYPT=${SKIP_LETS_ENCRYPT:-n}
|
||||||
|
- ENABLE_SSL_SNI=${ENABLE_SSL_SNI:-n}
|
||||||
|
- SKIP_IP_CHECK=${SKIP_IP_CHECK:-n}
|
||||||
|
- SKIP_HTTP_VERIFICATION=${SKIP_HTTP_VERIFICATION:-n}
|
||||||
|
- ONLY_MAILCOW_HOSTNAME=${ONLY_MAILCOW_HOSTNAME:-n}
|
||||||
|
- LE_STAGING=${LE_STAGING:-n}
|
||||||
|
- TZ=${TZ}
|
||||||
|
- REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
|
||||||
|
- REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
|
||||||
|
- SNAT_TO_SOURCE=${SNAT_TO_SOURCE:-n}
|
||||||
|
- SNAT6_TO_SOURCE=${SNAT6_TO_SOURCE:-n}
|
||||||
|
volumes:
|
||||||
|
- ./data/web/.well-known/acme-challenge:/var/www/acme:rw
|
||||||
|
- ./data/assets/ssl:/var/lib/acme/:rw
|
||||||
|
- ./data/assets/ssl-example:/var/lib/ssl-example/:ro
|
||||||
|
- mysql-socket-vol-1:/var/run/mysqld/
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
mailcow-network:
|
||||||
|
aliases:
|
||||||
|
- acme
|
||||||
|
|
||||||
|
netfilter-mailcow:
|
||||||
|
image: mailcow/netfilter:1.36
|
||||||
|
stop_grace_period: 30s
|
||||||
|
depends_on:
|
||||||
|
- dovecot-mailcow
|
||||||
|
- postfix-mailcow
|
||||||
|
- sogo-mailcow
|
||||||
|
- php-fpm-mailcow
|
||||||
|
- redis-mailcow
|
||||||
|
restart: always
|
||||||
|
privileged: true
|
||||||
|
environment:
|
||||||
|
- TZ=${TZ}
|
||||||
|
- IPV4_NETWORK=${IPV4_NETWORK:-172.22.1}
|
||||||
|
- IPV6_NETWORK=${IPV6_NETWORK:-fd4d:6169:6c63:6f77::/64}
|
||||||
|
- SNAT_TO_SOURCE=${SNAT_TO_SOURCE:-n}
|
||||||
|
- SNAT6_TO_SOURCE=${SNAT6_TO_SOURCE:-n}
|
||||||
|
- REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
|
||||||
|
- REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
|
||||||
|
network_mode: "host"
|
||||||
|
volumes:
|
||||||
|
- /lib/modules:/lib/modules:ro
|
||||||
|
|
||||||
|
watchdog-mailcow:
|
||||||
|
image: mailcow/watchdog:1.77
|
||||||
|
# Debug
|
||||||
|
#command: /watchdog.sh
|
||||||
|
dns:
|
||||||
|
- ${IPV4_NETWORK:-172.22.1}.254
|
||||||
|
volumes:
|
||||||
|
- rspamd-vol-1:/var/lib/rspamd
|
||||||
|
- mysql-socket-vol-1:/var/run/mysqld/
|
||||||
|
- ./data/assets/ssl:/etc/ssl/mail/:ro
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
- IPV6_NETWORK=${IPV6_NETWORK:-fd4d:6169:6c63:6f77::/64}
|
||||||
|
- LOG_LINES=${LOG_LINES:-9999}
|
||||||
|
- TZ=${TZ}
|
||||||
|
- DBNAME=${DBNAME}
|
||||||
|
- DBUSER=${DBUSER}
|
||||||
|
- DBPASS=${DBPASS}
|
||||||
|
- DBROOT=${DBROOT}
|
||||||
|
- USE_WATCHDOG=${USE_WATCHDOG:-n}
|
||||||
|
- WATCHDOG_NOTIFY_EMAIL=${WATCHDOG_NOTIFY_EMAIL}
|
||||||
|
- WATCHDOG_NOTIFY_BAN=${WATCHDOG_NOTIFY_BAN:-y}
|
||||||
|
- WATCHDOG_EXTERNAL_CHECKS=${WATCHDOG_EXTERNAL_CHECKS:-n}
|
||||||
|
- WATCHDOG_MYSQL_REPLICATION_CHECKS=${WATCHDOG_MYSQL_REPLICATION_CHECKS:-n}
|
||||||
|
- MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME}
|
||||||
|
- IPV4_NETWORK=${IPV4_NETWORK:-172.22.1}
|
||||||
|
- IP_BY_DOCKER_API=${IP_BY_DOCKER_API:-0}
|
||||||
|
- CHECK_UNBOUND=${CHECK_UNBOUND:-1}
|
||||||
|
- SKIP_CLAMD=${SKIP_CLAMD:-n}
|
||||||
|
- SKIP_LETS_ENCRYPT=${SKIP_LETS_ENCRYPT:-n}
|
||||||
|
- SKIP_SOGO=${SKIP_SOGO:-n}
|
||||||
|
- HTTPS_PORT=${HTTPS_PORT:-443}
|
||||||
|
- REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
|
||||||
|
- REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
|
||||||
|
- EXTERNAL_CHECKS_THRESHOLD=1
|
||||||
|
- NGINX_THRESHOLD=5
|
||||||
|
- UNBOUND_THRESHOLD=5
|
||||||
|
- REDIS_THRESHOLD=5
|
||||||
|
- MYSQL_THRESHOLD=5
|
||||||
|
- MYSQL_REPLICATION_THRESHOLD=1
|
||||||
|
- SOGO_THRESHOLD=3
|
||||||
|
- POSTFIX_THRESHOLD=8
|
||||||
|
- CLAMD_THRESHOLD=15
|
||||||
|
- DOVECOT_THRESHOLD=12
|
||||||
|
- DOVECOT_REPL_THRESHOLD=2
|
||||||
|
- PHPFPM_THRESHOLD=5
|
||||||
|
- RATELIMIT_THRESHOLD=1
|
||||||
|
- FAIL2BAN_THRESHOLD=1
|
||||||
|
- ACME_THRESHOLD=1
|
||||||
|
- IPV6NAT_THRESHOLD=1
|
||||||
|
- RSPAMD_THRESHOLD=5
|
||||||
|
- OLEFY_THRESHOLD=5
|
||||||
|
networks:
|
||||||
|
mailcow-network:
|
||||||
|
aliases:
|
||||||
|
- watchdog
|
||||||
|
|
||||||
|
dockerapi-mailcow:
|
||||||
|
image: mailcow/dockerapi:1.37
|
||||||
|
restart: always
|
||||||
|
oom_kill_disable: true
|
||||||
|
dns:
|
||||||
|
- ${IPV4_NETWORK:-172.22.1}.254
|
||||||
|
environment:
|
||||||
|
- DBROOT=${DBROOT}
|
||||||
|
- TZ=${TZ}
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||||
|
networks:
|
||||||
|
mailcow-network:
|
||||||
|
aliases:
|
||||||
|
- dockerapi
|
||||||
|
|
||||||
|
solr-mailcow:
|
||||||
|
image: mailcow/solr:1.7
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- solr-vol-1:/opt/solr/server/solr/dovecot-fts/data
|
||||||
|
ports:
|
||||||
|
- "${SOLR_PORT:-127.0.0.1:18983}:8983"
|
||||||
|
environment:
|
||||||
|
- TZ=${TZ}
|
||||||
|
- SOLR_HEAP=${SOLR_HEAP:-1024}
|
||||||
|
- SKIP_SOLR=${SKIP_SOLR:-y}
|
||||||
|
networks:
|
||||||
|
mailcow-network:
|
||||||
|
aliases:
|
||||||
|
- solr
|
||||||
|
|
||||||
|
olefy-mailcow:
|
||||||
|
image: mailcow/olefy:1.3
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
- TZ=${TZ}
|
||||||
|
- OLEFY_BINDADDRESS=0.0.0.0
|
||||||
|
- OLEFY_BINDPORT=10055
|
||||||
|
- OLEFY_TMPDIR=/tmp
|
||||||
|
- OLEFY_PYTHON_PATH=/usr/bin/python3
|
||||||
|
- OLEFY_OLEVBA_PATH=/usr/bin/olevba3
|
||||||
|
- OLEFY_LOGLVL=20
|
||||||
|
- OLEFY_MINLENGTH=500
|
||||||
|
- OLEFY_DEL_TMP=1
|
||||||
|
networks:
|
||||||
|
mailcow-network:
|
||||||
|
aliases:
|
||||||
|
- olefy
|
||||||
|
|
||||||
|
ipv6nat-mailcow:
|
||||||
|
depends_on:
|
||||||
|
- unbound-mailcow
|
||||||
|
- mysql-mailcow
|
||||||
|
- redis-mailcow
|
||||||
|
- clamd-mailcow
|
||||||
|
- rspamd-mailcow
|
||||||
|
- php-fpm-mailcow
|
||||||
|
- sogo-mailcow
|
||||||
|
- dovecot-mailcow
|
||||||
|
- postfix-mailcow
|
||||||
|
- memcached-mailcow
|
||||||
|
- nginx-mailcow
|
||||||
|
- acme-mailcow
|
||||||
|
- netfilter-mailcow
|
||||||
|
- watchdog-mailcow
|
||||||
|
- dockerapi-mailcow
|
||||||
|
- solr-mailcow
|
||||||
|
environment:
|
||||||
|
- TZ=${TZ}
|
||||||
|
image: robbertkl/ipv6nat
|
||||||
|
restart: always
|
||||||
|
privileged: true
|
||||||
|
network_mode: "host"
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||||
|
- /lib/modules:/lib/modules:ro
|
||||||
|
|
||||||
|
|
||||||
|
gitlab:
|
||||||
|
image: 'gitlab/gitlab-ce:latest'
|
||||||
|
container_name: 'gitlab'
|
||||||
|
restart: always
|
||||||
|
hostname: 'localhost'
|
||||||
|
environment:
|
||||||
|
GITLAB_OMNIBUS_CONFIG: |
|
||||||
|
external_url 'https://aitrainer.app:8929'
|
||||||
|
gitlab_rails['smtp_enable'] = true
|
||||||
|
gitlab_rails['smtp_address'] = "email-smtp.eu-west-1.amazonaws.com"
|
||||||
|
gitlab_rails['smtp_port'] = 587
|
||||||
|
gitlab_rails['smtp_user_name'] = "AKIAIWHHQDMPADT7ETHQ"
|
||||||
|
gitlab_rails['smtp_password'] = "AjCB8NA+61i/URp09gik0HHtbEuy48e4JXhuPaqGacFs"
|
||||||
|
gitlab_rails['smtp_domain'] = "aitrainer.app"
|
||||||
|
gitlab_rails['smtp_authentication'] = "login"
|
||||||
|
gitlab_rails['smtp_enable_starttls_auto'] = true
|
||||||
|
gitlab_rails['smtp_openssl_verify_mode'] = 'peer'
|
||||||
|
# Add any other gitlab.rb configuration here, each on its own line
|
||||||
|
gitlab_rails['gitlab_shell_ssh_port'] = 6622
|
||||||
|
ports:
|
||||||
|
- '8929:8929'
|
||||||
|
- '443:443'
|
||||||
|
- '6622:22'
|
||||||
|
- '587:587'
|
||||||
|
volumes:
|
||||||
|
- '/srv/gitlab/config:/etc/gitlab'
|
||||||
|
- '/srv/gitlab/logs:/var/log/gitlab'
|
||||||
|
- '/srv/gitlab/data:/var/opt/gitlab'
|
||||||
|
|
||||||
|
mysql:
|
||||||
|
image: mysql:latest
|
||||||
|
volumes:
|
||||||
|
- mysql-vol-0:/var/lib/mysql0
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- 33061:33061
|
||||||
|
environment:
|
||||||
|
MYSQL_ROOT_PASSWORD: /run/secrets/mysql_root_pwd
|
||||||
|
MYSQL_DATABASE: aitrainer
|
||||||
|
MYSQL_USER: aitrainer
|
||||||
|
MYSQL_PASSWORD: /run/secrets/mysql_user_pwd
|
||||||
|
networks:
|
||||||
|
- bosi_default
|
||||||
|
|
||||||
|
phpmyadmin:
|
||||||
|
depends_on:
|
||||||
|
- mysql
|
||||||
|
image: phpmyadmin/phpmyadmin
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- '80:80'
|
||||||
|
environment:
|
||||||
|
PMA_HOST: mysql
|
||||||
|
MYSQL_ROOT_PASSWORD: andio2009
|
||||||
|
networks:
|
||||||
|
- bosi_default
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- /srv/gitlab-runner/config:/etc/gitlab-runner
|
||||||
|
|
||||||
|
|
||||||
|
networks:
|
||||||
|
bosi_default:
|
||||||
|
mailcow-network:
|
||||||
|
driver: bridge
|
||||||
|
driver_opts:
|
||||||
|
com.docker.network.bridge.name: br-mailcow
|
||||||
|
enable_ipv6: true
|
||||||
|
ipam:
|
||||||
|
driver: default
|
||||||
|
config:
|
||||||
|
- subnet: ${IPV4_NETWORK:-172.22.1}.0/24
|
||||||
|
- subnet: ${IPV6_NETWORK:-fd4d:6169:6c63:6f77::/64}
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
# Storage for email files
|
||||||
|
vmail-vol-1:
|
||||||
|
# Storage for attachments (deduplicated)
|
||||||
|
vmail-attachments-vol-1:
|
||||||
|
mysql-vol-1:
|
||||||
|
mysql-vol-0:
|
||||||
|
mysql-socket-vol-1:
|
||||||
|
redis-vol-1:
|
||||||
|
rspamd-vol-1:
|
||||||
|
solr-vol-1:
|
||||||
|
postfix-vol-1:
|
||||||
|
crypt-vol-1:
|
||||||
|
sogo-web-vol-1:
|
||||||
|
sogo-userdata-backup-vol-1:
|
||||||
|
php:
|
||||||
|
|
||||||
|
secrets:
|
||||||
|
mysql_root_pwd:
|
||||||
|
file: /.sec/mysql_root_pwd
|
||||||
|
mysql_user_pwd:
|
||||||
|
file: /.sec/mysql_user_pwd
|
||||||
|
|
||||||
|
|
143
data/config/docker-compose_gitlab.yml
Normal file
143
data/config/docker-compose_gitlab.yml
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
version: '3.8'
|
||||||
|
services:
|
||||||
|
|
||||||
|
demo:
|
||||||
|
image: ehazlett/docker-demo
|
||||||
|
deploy:
|
||||||
|
replicas: 1
|
||||||
|
labels:
|
||||||
|
com.docker.lb.hosts: aitrainer.app
|
||||||
|
com.docker.lb.network: bosi-network
|
||||||
|
com.docker.lb.port: 8080
|
||||||
|
com.docker.lb.ssl_cert: demo_app.example.org.cert
|
||||||
|
com.docker.lb.ssl_key: demo_app.example.org.key
|
||||||
|
environment:
|
||||||
|
METADATA: proxy-handles-tls
|
||||||
|
networks:
|
||||||
|
- demo-network
|
||||||
|
|
||||||
|
gitlab:
|
||||||
|
image: 'gitlab/gitlab-ce:latest'
|
||||||
|
container_name: 'gitlab'
|
||||||
|
restart: always
|
||||||
|
hostname: 'localhost'
|
||||||
|
environment:
|
||||||
|
GITLAB_OMNIBUS_CONFIG: |
|
||||||
|
external_url 'https://aitrainer.app'
|
||||||
|
gitlab_rails['smtp_enable'] = true
|
||||||
|
gitlab_rails['smtp_address'] = "email-smtp.eu-west-1.amazonaws.com"
|
||||||
|
gitlab_rails['smtp_port'] = 587
|
||||||
|
gitlab_rails['smtp_user_name'] = "AKIAIWHHQDMPADT7ETHQ"
|
||||||
|
gitlab_rails['smtp_password'] = "AjCB8NA+61i/URp09gik0HHtbEuy48e4JXhuPaqGacFs"
|
||||||
|
gitlab_rails['smtp_domain'] = "aitrainer.app"
|
||||||
|
gitlab_rails['smtp_authentication'] = "login"
|
||||||
|
gitlab_rails['smtp_enable_starttls_auto'] = true
|
||||||
|
gitlab_rails['smtp_openssl_verify_mode'] = 'peer'
|
||||||
|
# Add any other gitlab.rb configuration here, each on its own line
|
||||||
|
gitlab_rails['gitlab_shell_ssh_port'] = 6622
|
||||||
|
ports:
|
||||||
|
- '80:80'
|
||||||
|
- '443:443'
|
||||||
|
- '6622:22'
|
||||||
|
- '587:587'
|
||||||
|
volumes:
|
||||||
|
- '/srv/gitlab/config:/etc/gitlab'
|
||||||
|
- '/srv/gitlab/logs:/var/log/gitlab'
|
||||||
|
- '/srv/gitlab/data:/var/opt/gitlab'
|
||||||
|
mysql:
|
||||||
|
image: mysql:latest
|
||||||
|
volumes:
|
||||||
|
- db_data:/var/lib/mysql_aitrainer
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- 33061:33061
|
||||||
|
environment:
|
||||||
|
MYSQL_ROOT_PASSWORD: /run/secrets/mysql_root_pwd
|
||||||
|
MYSQL_DATABASE: aitrainer
|
||||||
|
MYSQL_USER: aitrainer
|
||||||
|
MYSQL_PASSWORD: /run/secrets/mysql_user_pwd
|
||||||
|
networks:
|
||||||
|
- bosi_default
|
||||||
|
|
||||||
|
phpmyadmin:
|
||||||
|
depends_on:
|
||||||
|
- mysql
|
||||||
|
image: phpmyadmin/phpmyadmin
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- '8081:80'
|
||||||
|
environment:
|
||||||
|
PMA_HOST: mysql
|
||||||
|
MYSQL_ROOT_PASSWORD: andio2009
|
||||||
|
networks:
|
||||||
|
- bosi_default
|
||||||
|
php:
|
||||||
|
image: php:7.2-fpm
|
||||||
|
volumes:
|
||||||
|
- php:/var/www/html
|
||||||
|
- ./php/php.ini:/usr/local/etc/php/php.ini
|
||||||
|
depends_on:
|
||||||
|
- mysql
|
||||||
|
gitlab-runner:
|
||||||
|
image: gitlab/gitlab-runner:latest
|
||||||
|
container_name: gitlab-runner
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
- bosi_default
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- /srv/gitlab-runner/config:/etc/gitlab-runner
|
||||||
|
secrets:
|
||||||
|
mysql_root_pwd:
|
||||||
|
file: /.sec/mysql_root_pwd
|
||||||
|
mysql_user_pwd:
|
||||||
|
file: /.sec/mysql_user_pwd
|
||||||
|
networks:
|
||||||
|
bosi_default:
|
||||||
|
volumes:
|
||||||
|
db_data:
|
||||||
|
php:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
openssl req \
|
||||||
|
-new \
|
||||||
|
-newkey rsa:4096 \
|
||||||
|
-days 3650 \
|
||||||
|
-nodes \
|
||||||
|
-x509 \
|
||||||
|
-subj "/C=US/ST=CA/L=SF/O=Docker-demo/CN=aitrainer.app" \
|
||||||
|
-keyout aitrainer.app.key \
|
||||||
|
-out aitrainer.app.cert
|
||||||
|
|
||||||
|
version: "3.2"
|
||||||
|
|
||||||
|
services:
|
||||||
|
demo:
|
||||||
|
image: proxy
|
||||||
|
command: --tls-cert=/run/secrets/cert.pem --tls-key=/run/secrets/key.pem
|
||||||
|
deploy:
|
||||||
|
replicas: 1
|
||||||
|
labels:
|
||||||
|
com.docker.lb.hosts: aitrainer.app
|
||||||
|
com.docker.lb.network: proxy-network
|
||||||
|
com.docker.lb.port: 8029
|
||||||
|
com.docker.lb.ssl_passthrough: "true"
|
||||||
|
environment:
|
||||||
|
METADATA: end-to-end-TLS
|
||||||
|
networks:
|
||||||
|
- proxy-network
|
||||||
|
secrets:
|
||||||
|
- source: aitrainer.app.cert
|
||||||
|
target: /run/secrets/cert.pem
|
||||||
|
- source: aitrainer.app.org.key
|
||||||
|
target: /run/secrets/key.pem
|
||||||
|
|
||||||
|
networks:
|
||||||
|
demo-network:
|
||||||
|
driver: overlay
|
||||||
|
secrets:
|
||||||
|
aitrainer.app.cert:
|
||||||
|
file: ./aitrainer.app.cert
|
||||||
|
aitrainer.app.key:
|
||||||
|
file: ./aitrainer.app.key
|
113
data/config/gitlab-nginx-ssl.conf
Normal file
113
data/config/gitlab-nginx-ssl.conf
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
## GitLab
|
||||||
|
##
|
||||||
|
## Modified from nginx http version
|
||||||
|
## Modified from http://blog.phusion.nl/2012/04/21/tutorial-setting-up-gitlab-on-debian-6/
|
||||||
|
## Modified from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
|
||||||
|
##
|
||||||
|
## Lines starting with two hashes (##) are comments with information.
|
||||||
|
## Lines starting with one hash (#) are configuration parameters that can be uncommented.
|
||||||
|
##
|
||||||
|
##################################
|
||||||
|
## CONTRIBUTING ##
|
||||||
|
##################################
|
||||||
|
##
|
||||||
|
## If you change this file in a Merge Request, please also create
|
||||||
|
## a Merge Request on https://gitlab.com/gitlab-org/omnibus-gitlab/merge_requests
|
||||||
|
##
|
||||||
|
###################################
|
||||||
|
## configuration ##
|
||||||
|
###################################
|
||||||
|
##
|
||||||
|
## See installation.md#using-https for additional HTTPS configuration details.
|
||||||
|
|
||||||
|
upstream gitlab-workhorse {
|
||||||
|
server unix:/srv/gitlab/gitlab-workhorse/socket fail_timeout=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
## Redirects all HTTP traffic to the HTTPS host
|
||||||
|
server {
|
||||||
|
## Either remove "default_server" from the listen line below,
|
||||||
|
## or delete the /etc/nginx/sites-enabled/default file. This will cause gitlab
|
||||||
|
## to be served if you visit any address that your server responds to, eg.
|
||||||
|
## the ip address of the server (http://x.x.x.x/)
|
||||||
|
listen 0.0.0.0:80;
|
||||||
|
listen [::]:80 ipv6only=on default_server;
|
||||||
|
server_name git.aitrainer.app ; ## Replace this with something like gitlab.example.com
|
||||||
|
server_tokens off; ## Don't show the nginx version number, a security best practice
|
||||||
|
return 301 https://$http_host$request_uri;
|
||||||
|
access_log /var/log/nginx/gitlab_access.log;
|
||||||
|
error_log /var/log/nginx/gitlab_error.log;
|
||||||
|
}
|
||||||
|
|
||||||
|
## HTTPS host
|
||||||
|
server {
|
||||||
|
listen 0.0.0.0:443 ssl;
|
||||||
|
listen [::]:443 ipv6only=on ssl default_server;
|
||||||
|
server_name git.aitrainer.app ; ## Replace this with something like gitlab.example.com
|
||||||
|
server_tokens off; ## Don't show the nginx version number, a security best practice
|
||||||
|
root /opt/gitlab/embedded/service/gitlab-rails/public;
|
||||||
|
|
||||||
|
## Strong SSL Security
|
||||||
|
## https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html & https://cipherli.st/
|
||||||
|
ssl on;
|
||||||
|
#ssl_certificate /etc/nginx/ssl/gitlab.crt;
|
||||||
|
#ssl_certificate_key /etc/nginx/ssl/gitlab.key;
|
||||||
|
ssl_certificate /etc/letsencrypt/live/git.aitrainer.app/fullchain.pem; # managed by Certbot
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/git.aitrainer.app/privkey.pem; # managed by Certbot
|
||||||
|
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
|
||||||
|
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
|
||||||
|
|
||||||
|
# GitLab needs backwards compatible ciphers to retain compatibility with Java IDEs
|
||||||
|
ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
|
||||||
|
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
ssl_session_cache shared:SSL:10m;
|
||||||
|
ssl_session_timeout 5m;
|
||||||
|
|
||||||
|
## See app/controllers/application_controller.rb for headers set
|
||||||
|
|
||||||
|
## [Optional] Enable HTTP Strict Transport Security
|
||||||
|
## HSTS is a feature improving protection against MITM attacks
|
||||||
|
## For more information see: https://www.nginx.com/blog/http-strict-transport-security-hsts-and-nginx/
|
||||||
|
# add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
|
||||||
|
|
||||||
|
## [Optional] If your certficate has OCSP, enable OCSP stapling to reduce the overhead and latency of running SSL.
|
||||||
|
## Replace with your ssl_trusted_certificate. For more info see:
|
||||||
|
## - https://medium.com/devops-programming/4445f4862461
|
||||||
|
## - https://www.ruby-forum.com/topic/4419319
|
||||||
|
## - https://www.digitalocean.com/community/tutorials/how-to-configure-ocsp-stapling-on-apache-and-nginx
|
||||||
|
# ssl_stapling on;
|
||||||
|
# ssl_stapling_verify on;
|
||||||
|
# ssl_trusted_certificate /etc/nginx/ssl/stapling.trusted.crt;
|
||||||
|
# resolver 208.67.222.222 208.67.222.220 valid=300s; # Can change to your DNS resolver if desired
|
||||||
|
# resolver_timeout 5s;
|
||||||
|
|
||||||
|
## [Optional] Generate a stronger DHE parameter:
|
||||||
|
## sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096
|
||||||
|
##
|
||||||
|
# ssl_dhparam /etc/ssl/certs/dhparam.pem;
|
||||||
|
|
||||||
|
## Individual nginx logs for this GitLab vhost
|
||||||
|
access_log /var/log/nginx/gitlab_access.log;
|
||||||
|
error_log /var/log/nginx/gitlab_error.log;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
client_max_body_size 0;
|
||||||
|
gzip off;
|
||||||
|
|
||||||
|
## https://github.com/gitlabhq/gitlabhq/issues/694
|
||||||
|
## Some requests take more than 30 seconds.
|
||||||
|
proxy_read_timeout 300;
|
||||||
|
proxy_connect_timeout 300;
|
||||||
|
proxy_redirect off;
|
||||||
|
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
|
||||||
|
proxy_set_header Host $http_host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-Ssl on;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_pass http://gitlab-workhorse;
|
||||||
|
}
|
||||||
|
}
|
138
data/db/install.sql
Normal file
138
data/db/install.sql
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
-- --------------------------------------------------------
|
||||||
|
-- Host: 127.0.0.1
|
||||||
|
-- Szerver verzió: 10.4.11-MariaDB - mariadb.org binary distribution
|
||||||
|
-- Szerver OS: Win64
|
||||||
|
-- HeidiSQL Verzió: 11.0.0.5919
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||||
|
/*!40101 SET NAMES utf8 */;
|
||||||
|
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||||
|
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||||
|
|
||||||
|
use aitrainer;
|
||||||
|
|
||||||
|
-- Struktúra mentése tábla aitrainer. customer
|
||||||
|
CREATE TABLE IF NOT EXISTS `customer` (
|
||||||
|
`customer_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`name` char(100) COLLATE utf8_hungarian_ci NOT NULL,
|
||||||
|
`firstname` char(100) COLLATE utf8_hungarian_ci NOT NULL,
|
||||||
|
`email` char(100) COLLATE utf8_hungarian_ci DEFAULT NULL,
|
||||||
|
`password` char(100) COLLATE utf8_hungarian_ci DEFAULT NULL,
|
||||||
|
`sex` enum('m','w') COLLATE utf8_hungarian_ci DEFAULT 'm',
|
||||||
|
`age` tinyint(4) DEFAULT NULL,
|
||||||
|
`active` enum('Y','N','D','S') COLLATE utf8_hungarian_ci DEFAULT 'N',
|
||||||
|
`date_add` datetime DEFAULT NULL,
|
||||||
|
`date_change` datetime DEFAULT NULL,
|
||||||
|
`data_policy_allowed` tinyint(4) DEFAULT 1,
|
||||||
|
`admin` tinyint(4) DEFAULT 0,
|
||||||
|
PRIMARY KEY (`customer_id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
|
||||||
|
|
||||||
|
-- Tábla adatainak mentése aitrainer.customer: ~13 rows (hozzávetőleg)
|
||||||
|
/*!40000 ALTER TABLE `customer` DISABLE KEYS */;
|
||||||
|
INSERT INTO `customer` (`customer_id`, `name`, `firstname`, `email`, `password`, `sex`, `age`, `active`, `date_add`, `date_change`, `data_policy_allowed`, `admin`) VALUES
|
||||||
|
(1, 'Átlag 13 éves fiú', '', NULL, NULL, 'm', 13, 'N', NULL, NULL, 1, 0),
|
||||||
|
(2, 'Átlag 14 éves fiú', '', NULL, NULL, 'm', 14, 'N', NULL, NULL, 1, 0),
|
||||||
|
(3, 'Átlag 15 éves fiú', '', NULL, NULL, 'm', 15, 'N', NULL, NULL, 1, 0),
|
||||||
|
(4, 'Átlag 15 éves fiú', '', NULL, NULL, 'm', 15, 'N', NULL, NULL, 1, 0),
|
||||||
|
(5, 'Átlag 16 éves fiú', '', NULL, NULL, 'm', 16, 'N', NULL, NULL, 1, 0),
|
||||||
|
(6, 'Átlag 17 éves fiú', '', NULL, NULL, 'm', 17, 'N', NULL, NULL, 1, 0),
|
||||||
|
(7, 'Átlag 18 éves fiú', '', NULL, NULL, 'm', 18, 'N', NULL, NULL, 1, 0),
|
||||||
|
(8, 'Átlag 13 éves lány', '', NULL, NULL, 'w', 13, 'N', NULL, NULL, 1, 0),
|
||||||
|
(9, 'Átlag 14 éves lány', '', NULL, NULL, 'w', 14, 'N', NULL, NULL, 1, 0),
|
||||||
|
(10, 'Átlag 15 éves lány', '', NULL, NULL, 'w', 15, 'N', NULL, NULL, 1, 0),
|
||||||
|
(11, 'Átlag 16 éves lány', '', NULL, NULL, 'w', 16, 'N', NULL, NULL, 1, 0),
|
||||||
|
(12, 'Átlag 17 éves lány', '', NULL, NULL, 'w', 17, 'N', NULL, NULL, 1, 0),
|
||||||
|
(13, 'Átlag 18 éves lány', '', NULL, NULL, 'w', 18, 'N', NULL, NULL, 1, 0);
|
||||||
|
/*!40000 ALTER TABLE `customer` ENABLE KEYS */;
|
||||||
|
|
||||||
|
-- Struktúra mentése tábla aitrainer. customer_information
|
||||||
|
CREATE TABLE IF NOT EXISTS `customer_information` (
|
||||||
|
`customer_information_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`title` char(50) COLLATE utf8_hungarian_ci DEFAULT '',
|
||||||
|
`description` mediumtext COLLATE utf8_hungarian_ci DEFAULT NULL,
|
||||||
|
`date_add` datetime DEFAULT NULL,
|
||||||
|
`display_begin` datetime DEFAULT NULL,
|
||||||
|
`display_end` datetime DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`customer_information_id`) USING BTREE,
|
||||||
|
KEY `title` (`title`) USING BTREE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
|
||||||
|
|
||||||
|
-- Tábla adatainak mentése aitrainer.customer_information: ~0 rows (hozzávetőleg)
|
||||||
|
/*!40000 ALTER TABLE `customer_information` DISABLE KEYS */;
|
||||||
|
/*!40000 ALTER TABLE `customer_information` ENABLE KEYS */;
|
||||||
|
|
||||||
|
INSERT INTO `customer_information` (`customer_information_id`, `title`, `description`, `date_add`, `display_begin`, `display_end`) VALUES (1, 'Fekvőtámasz világcsúcs', 'Világcsúcs fekvőtámasz: KJ Joseph 1 perc alatt 82 szabályos fekvőtámaszt végzett', '2020-06-01 08:00:00', '2020-06-01 08:00:00', '2023-07-01 08:00:00');
|
||||||
|
INSERT INTO `customer_information` (`customer_information_id`, `title`, `description`, `date_add`, `display_begin`, `display_end`) VALUES (2, 'Húzódszkodás csúcs', '24 órás csúcstartója Joonas Mäkipelto 5050 gyakorlattal', '2020-06-01 08:00:00', '2020-06-01 08:00:00', '2023-07-01 08:00:00');
|
||||||
|
INSERT INTO `customer_information` (`customer_information_id`, `title`, `description`, `date_add`, `display_begin`, `display_end`) VALUES (3, 'Fekvenyomás', '2015-ben a fekvenyomó világbajnokságot Smulter Fredrik finn súlyemelő 401 Kg-al nyerte', '2020-06-01 08:00:00', '2020-05-01 00:00:00', '2020-06-01 08:00:01');
|
||||||
|
|
||||||
|
|
||||||
|
-- Struktúra mentése tábla aitrainer. exercises
|
||||||
|
CREATE TABLE IF NOT EXISTS `exercises` (
|
||||||
|
`exercise_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`exercise_type_id` int(11) NOT NULL,
|
||||||
|
`customer_id` int(11) NOT NULL,
|
||||||
|
`date_add` datetime NOT NULL,
|
||||||
|
`quantity` float DEFAULT NULL,
|
||||||
|
`unit` enum('kg','meter','repeat','minute') COLLATE utf8_hungarian_ci DEFAULT 'repeat',
|
||||||
|
`rest_time` int(11) DEFAULT NULL COMMENT 'in sec',
|
||||||
|
PRIMARY KEY (`exercise_id`),
|
||||||
|
KEY `exercise_type_id` (`exercise_type_id`),
|
||||||
|
KEY `customer_id` (`customer_id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
|
||||||
|
|
||||||
|
-- Tábla adatainak mentése aitrainer.exercises: ~0 rows (hozzávetőleg)
|
||||||
|
/*!40000 ALTER TABLE `exercises` DISABLE KEYS */;
|
||||||
|
INSERT INTO `exercises` (`exercise_id`, `exercise_type_id`, `customer_id`, `date_add`, `quantity`, `unit`, `rest_time`) VALUES
|
||||||
|
(1, 1, 1, '2020-05-01 00:00:00', 12, 'repeat', NULL);
|
||||||
|
/*!40000 ALTER TABLE `exercises` ENABLE KEYS */;
|
||||||
|
|
||||||
|
-- Struktúra mentése tábla aitrainer. exercise_evaluation
|
||||||
|
CREATE TABLE IF NOT EXISTS `exercise_evaluation` (
|
||||||
|
`evaluation_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`age_min` int(11) DEFAULT 0,
|
||||||
|
`age_max` int(11) DEFAULT 0,
|
||||||
|
`value_min` int(11) DEFAULT 0,
|
||||||
|
`value_max` int(11) DEFAULT 0,
|
||||||
|
`sex` enum('m','w') COLLATE utf8_hungarian_ci NOT NULL DEFAULT 'm',
|
||||||
|
`evaluation` enum('excellent','very good','good','average','weak','poor') COLLATE utf8_hungarian_ci NOT NULL DEFAULT 'average',
|
||||||
|
`description` mediumtext COLLATE utf8_hungarian_ci DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`evaluation_id`) USING BTREE,
|
||||||
|
KEY `value_min_value_max` (`value_min`,`value_max`) USING BTREE,
|
||||||
|
KEY `age_min_age_max` (`age_min`,`age_max`) USING BTREE,
|
||||||
|
KEY `age_min_age_max_value_min_value_max` (`age_min`,`age_max`,`value_min`,`value_max`) USING BTREE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
|
||||||
|
|
||||||
|
-- Tábla adatainak mentése aitrainer.exercise_evaluation: ~0 rows (hozzávetőleg)
|
||||||
|
/*!40000 ALTER TABLE `exercise_evaluation` DISABLE KEYS */;
|
||||||
|
/*!40000 ALTER TABLE `exercise_evaluation` ENABLE KEYS */;
|
||||||
|
|
||||||
|
-- Struktúra mentése tábla aitrainer. exercise_type
|
||||||
|
CREATE TABLE IF NOT EXISTS `exercise_type` (
|
||||||
|
`exercise_type_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`name` char(100) COLLATE utf8_hungarian_ci NOT NULL,
|
||||||
|
`description` varchar(1000) COLLATE utf8_hungarian_ci DEFAULT NULL,
|
||||||
|
`video` mediumblob DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`exercise_type_id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
|
||||||
|
|
||||||
|
-- Tábla adatainak mentése aitrainer.exercise_type: ~11 rows (hozzávetőleg)
|
||||||
|
/*!40000 ALTER TABLE `exercise_type` DISABLE KEYS */;
|
||||||
|
INSERT INTO `exercise_type` (`exercise_type_id`, `name`, `description`, `video`) VALUES
|
||||||
|
(1, 'Melső fekvőtámasz 1 perc', 'Ezt igazolja a 2016 márciusában beállított guinness rekord is,\r\namelyben KJ Joseph 1 perc alatt 82 szabályos karhajlítás-nyújtást\r\nvégzett.', NULL),
|
||||||
|
(2, 'Húzódzkodás', 'Ennek a gyakorlatnak a 24 órás csúcstartója Joonas Mäkipelto 5050\r\ngyakorlattal.', NULL),
|
||||||
|
(3, 'Melső fekvőtámasz 30mp', 'A gyakorlatot 30 másodperc alatt olyan sokszor kell végrehajtani, ahányszor a\r\nfelvételiző képes rá. Azonban törekedni kell a szabályos végrehajtásra, ugyanis csak azokat\r\nszámolják. A nők esetében 20, a férfiak esetében 35 gyakorlatot kell végrehajtani a maximális\r\npont megszerzéséért. A gyakorlat akkor sikeres, ha a női legalább 1, a férfi felvételiző\r\nlegalább 11 gyakorlatot képes végrehajtani.', NULL),
|
||||||
|
(4, 'Melső fekvőtámasz 2perc', 'Magyar Honvédség: A gyakorlat végrehajtására 2 perc áll rendelkezésre. Ennek során csak a szabályosan a\r\nfentiekben leírt módon végrehajtott gyakorlat értékelhető. Férfiaknál 70 karhajlítás nyújtást\r\nkell végrehajtani a maximális pontért.', NULL),
|
||||||
|
(5, 'Hajlított karú függés', 'A gyakorlat addig tart, amíg a végrehajtó szemmagassága a kiinduló helyzettől\r\nsüllyedve a keresztvas alá nem kerül. Az értékeléshez stopperórát alkalmaznak, és az\r\neredmény másodperc pontossággal kerül megállapításra. Nők esetében 45, férfiak\r\ntekintetében 73 másodperctől jár a maximális pontszám. A gyakorlat sikeres végrehajtásához\r\nlegalább 8, 10 másodpercig kell megtartaniuk a kiinduló helyzetet a női és a férfi\r\nfelvételizőknek.\r\n\r\nA NKE-RTK-án lévő hallgatók egyéni rekordjai Iván Viktor 90s, Kiss Regina 74s', NULL),
|
||||||
|
(6, 'Fekvenyomás', '2015-ben a fekvenyomó világbajnokságot Smulter Fredrik finn súlyemelő 401 Kg-al nyerte.\r\nA súlyzó tömege nők esetében 25 kg, a férfiak esetében 60 kg a rúddal együtt. Az\r\nértékelésénél a szabályosan végrehajtott gyakorlatokat értékelik csak.\r\nA legtöbb pontért 25 gyakorlatot kell végezni mind a nőknek, mind a férfiaknak. A minimum:\r\negy gyakorlat mindkét nem esetében.', NULL),
|
||||||
|
(7, '4x10m-es ingafutás', 'A legjobb pontszámért 9,4 s illetve 8,8s alatt kell teljesíteni a nőknek, férfiaknak. A\r\ngyakorlat sikertelen 11,8 s illetve 11,2 s-on túl.', NULL),
|
||||||
|
(8, 'Helyből távolugrás', 'Byron Jones 2015-ben a 3,73 méteres ugrásával érte el a világcsúcsot.\r\nA nőknek 220 cm-re, a férfiak 250 cm-re kell ugraniuk a maximális pontért. A\r\nminimális távolság 172cm illetve 198 cm.', NULL),
|
||||||
|
(9, 'Felülés hanyattfekvésből', 'Az NKE-RTK hallgatói közül Papp Zsófia 66 db-ot, Gál Valentin 80\r\ndb-ot csinált 1 perc leforgása alatt.\r\nElső ütemre megtörténik a felülés, ami akkor szabályos, ha valamelyik könyök érinti a\r\ntérdet. Második ütemre vissza kell térni a kiinduló helyzetbe. A maximális pont eléréséhez 1\r\nperc alatt 45 illetve 55 ismétlést kell végezni a nőknek illetve a férfiaknak. A minimumhoz 7\r\nés 25 ismétlés szükséges.', NULL),
|
||||||
|
(10, 'Felülés hajlított térddel', 'Magyar Honvédség: A kiinduló helyzet hajlított ülés, ennek során a sarkak a talajon, a térd 90 fokban meghajlítva\r\nvan.\r\nA gyakorlat végrehajtására két perc áll rendelkezésre. Ennek során csak a szabályosan,\r\na fentiekben leírt módon végrehajtott gyakorlat értékelhető. Férfiaknál, nőknél egyaránt 90\r\ngyakorlatot kell végrehajtani a maximális pontért. Amennyiben a megadott időkeret alatt nem\r\nsikerül legalább 25 szabályos gyakorlatot végrehajtani, úgy az sikertelennek minősül.', NULL),
|
||||||
|
(11, 'Síkfutás 2000m', 'A maximálisan megszerezhető pontot az a felvételiző gyűjtheti be, aki a távot nők\r\nesetében 10:00 perc alatt, férfiak esetében 7:35 perc alatt teljesíti. A gyakorlat sikeres\r\nteljesítésére nők esetében maximum 16:00 perc, férfiak esetében 13:30 perc áll rendelkezésre.', NULL);
|
||||||
|
/*!40000 ALTER TABLE `exercise_type` ENABLE KEYS */;
|
||||||
|
|
||||||
|
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
|
||||||
|
/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
|
||||||
|
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
115
data/db/install_0_0_1.sql
Normal file
115
data/db/install_0_0_1.sql
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
-- --------------------------------------------------------
|
||||||
|
-- Host: 127.0.0.1
|
||||||
|
-- Szerver verzió: 8.0.20 - MySQL Community Server - GPL
|
||||||
|
-- Szerver OS: Win64
|
||||||
|
-- HeidiSQL Verzió: 11.0.0.5919
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||||
|
/*!40101 SET NAMES utf8 */;
|
||||||
|
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||||
|
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||||
|
|
||||||
|
use aitrainer;
|
||||||
|
|
||||||
|
-- Struktúra mentése tábla aitrainer. customer
|
||||||
|
CREATE TABLE IF NOT EXISTS `customer` (
|
||||||
|
`customer_id` int NOT NULL AUTO_INCREMENT,
|
||||||
|
`name` char(100) NOT NULL,
|
||||||
|
`firstname` char(100) NOT NULL,
|
||||||
|
`email` char(100) DEFAULT NULL,
|
||||||
|
`sex` enum('m','w') DEFAULT 'm',
|
||||||
|
`age` tinyint DEFAULT NULL,
|
||||||
|
`active` enum('Y','N','D','S') DEFAULT 'N',
|
||||||
|
PRIMARY KEY (`customer_id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
|
||||||
|
|
||||||
|
-- Tábla adatainak mentése aitrainer.customer: ~15 rows (hozzávetőleg)
|
||||||
|
/*!40000 ALTER TABLE `customer` DISABLE KEYS */;
|
||||||
|
INSERT INTO `customer` (`customer_id`, `name`, `firstname`, `email`, `sex`, `age`) VALUES
|
||||||
|
(1, 'Átlag 13 éves fiú', '', NULL, 'm', 13),
|
||||||
|
(2, 'Átlag 14 éves fiú', '', NULL, 'm', 14),
|
||||||
|
(3, 'Átlag 15 éves fiú', '', NULL, 'm', 15),
|
||||||
|
(4, 'Átlag 15 éves fiú', '', NULL, 'm', 15),
|
||||||
|
(5, 'Átlag 16 éves fiú', '', NULL, 'm', 16),
|
||||||
|
(6, 'Átlag 17 éves fiú', '', NULL, 'm', 17),
|
||||||
|
(7, 'Átlag 18 éves fiú', '', NULL, 'm', 18),
|
||||||
|
(8, 'Átlag 13 éves lány', '', NULL, 'w', 13),
|
||||||
|
(9, 'Átlag 14 éves lány', '', NULL, 'w', 14),
|
||||||
|
(10, 'Átlag 15 éves lány', '', NULL, 'w', 15),
|
||||||
|
(11, 'Átlag 16 éves lány', '', NULL, 'w', 16),
|
||||||
|
(12, 'Átlag 17 éves lány', '', NULL, 'w', 17),
|
||||||
|
(13, 'Átlag 18 éves lány', '', NULL, 'w', 18);
|
||||||
|
/*!40000 ALTER TABLE `customer` ENABLE KEYS */;
|
||||||
|
|
||||||
|
-- Struktúra mentése tábla aitrainer. exercises
|
||||||
|
CREATE TABLE IF NOT EXISTS `exercises` (
|
||||||
|
`exercise_id` int NOT NULL AUTO_INCREMENT,
|
||||||
|
`exercise_type_id` int NOT NULL,
|
||||||
|
`customer_id` int NOT NULL,
|
||||||
|
`datetime_exercise` datetime NOT NULL,
|
||||||
|
`quantity` float DEFAULT NULL,
|
||||||
|
`rest_time` int DEFAULT NULL COMMENT 'in sec',
|
||||||
|
PRIMARY KEY (`exercise_id`),
|
||||||
|
KEY `exercise_type_id` (`exercise_type_id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
|
||||||
|
|
||||||
|
-- Tábla adatainak mentése aitrainer.exercises: ~1 rows (hozzávetőleg)
|
||||||
|
/*!40000 ALTER TABLE `exercises` DISABLE KEYS */;
|
||||||
|
INSERT INTO `exercises` (`exercise_id`, `exercise_type_id`, `customer_id`, `datetime_exercise`, `quantity`, `rest_time`) VALUES
|
||||||
|
(1, 1, 1, '2020-05-01 00:00:00', 12, NULL);
|
||||||
|
/*!40000 ALTER TABLE `exercises` ENABLE KEYS */;
|
||||||
|
|
||||||
|
-- Struktúra mentése tábla aitrainer. exercise_ages
|
||||||
|
CREATE TABLE IF NOT EXISTS `exercise_ages` (
|
||||||
|
`exercise_age_id` int NOT NULL AUTO_INCREMENT,
|
||||||
|
`exercise_type_id` int NOT NULL,
|
||||||
|
`name` char(100) NOT NULL,
|
||||||
|
`sex` enum('m','w') DEFAULT 'm',
|
||||||
|
`age` tinyint DEFAULT NULL,
|
||||||
|
`min_exercises` int DEFAULT NULL,
|
||||||
|
`avg_exercises` int DEFAULT NULL,
|
||||||
|
`max_exercises` int DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`exercise_age_id`),
|
||||||
|
UNIQUE KEY `exercise_type_id_2` (`exercise_type_id`,`sex`,`age`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
|
||||||
|
|
||||||
|
-- Tábla adatainak mentése aitrainer.exercise_ages: ~6 rows (hozzávetőleg)
|
||||||
|
/*!40000 ALTER TABLE `exercise_ages` DISABLE KEYS */;
|
||||||
|
INSERT INTO `exercise_ages` (`exercise_age_id`, `exercise_type_id`, `name`, `sex`, `age`, `min_exercises`, `avg_exercises`, `max_exercises`) VALUES
|
||||||
|
(1, 1, '', 'm', 13, 12, NULL, NULL),
|
||||||
|
(2, 1, '', 'm', 14, 14, NULL, NULL),
|
||||||
|
(3, 1, '', 'm', 15, 16, NULL, NULL),
|
||||||
|
(4, 1, '', 'm', 16, 18, NULL, NULL),
|
||||||
|
(7, 1, '', 'm', 17, 18, NULL, NULL),
|
||||||
|
(8, 1, '', 'm', 18, 18, NULL, NULL);
|
||||||
|
/*!40000 ALTER TABLE `exercise_ages` ENABLE KEYS */;
|
||||||
|
|
||||||
|
-- Struktúra mentése tábla aitrainer. exercise_types
|
||||||
|
CREATE TABLE IF NOT EXISTS `exercise_type` (
|
||||||
|
`exercise_type_id` int NOT NULL AUTO_INCREMENT,
|
||||||
|
`name` char(100) NOT NULL,
|
||||||
|
`description` varchar(1000) DEFAULT NULL,
|
||||||
|
`video` mediumblob,
|
||||||
|
PRIMARY KEY (`exercise_type_id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
|
||||||
|
|
||||||
|
-- Tábla adatainak mentése aitrainer.exercise_types: ~11 rows (hozzávetőleg)
|
||||||
|
/*!40000 ALTER TABLE `exercise_type` DISABLE KEYS */;
|
||||||
|
INSERT INTO `exercise_type` (`exercise_type_id`, `name`, `description`, `video`) VALUES
|
||||||
|
(1, 'Melső fekvőtámasz 1 perc', 'Ezt igazolja a 2016 márciusában beállított guinness rekord is,\r\namelyben KJ Joseph 1 perc alatt 82 szabályos karhajlítás-nyújtást\r\nvégzett.', NULL),
|
||||||
|
(2, 'Húzódzkodás', 'Ennek a gyakorlatnak a 24 órás csúcstartója Joonas Mäkipelto 5050\r\ngyakorlattal.', NULL),
|
||||||
|
(3, 'Melső fekvőtámasz 30mp', 'A gyakorlatot 30 másodperc alatt olyan sokszor kell végrehajtani, ahányszor a\r\nfelvételiző képes rá. Azonban törekedni kell a szabályos végrehajtásra, ugyanis csak azokat\r\nszámolják. A nők esetében 20, a férfiak esetében 35 gyakorlatot kell végrehajtani a maximális\r\npont megszerzéséért. A gyakorlat akkor sikeres, ha a női legalább 1, a férfi felvételiző\r\nlegalább 11 gyakorlatot képes végrehajtani.', NULL),
|
||||||
|
(4, 'Melső fekvőtámasz 2perc', 'Magyar Honvédség: A gyakorlat végrehajtására 2 perc áll rendelkezésre. Ennek során csak a szabályosan a\r\nfentiekben leírt módon végrehajtott gyakorlat értékelhető. Férfiaknál 70 karhajlítás nyújtást\r\nkell végrehajtani a maximális pontért.', NULL),
|
||||||
|
(5, 'Hajlított karú függés', 'A gyakorlat addig tart, amíg a végrehajtó szemmagassága a kiinduló helyzettől\r\nsüllyedve a keresztvas alá nem kerül. Az értékeléshez stopperórát alkalmaznak, és az\r\neredmény másodperc pontossággal kerül megállapításra. Nők esetében 45, férfiak\r\ntekintetében 73 másodperctől jár a maximális pontszám. A gyakorlat sikeres végrehajtásához\r\nlegalább 8, 10 másodpercig kell megtartaniuk a kiinduló helyzetet a női és a férfi\r\nfelvételizőknek.\r\n\r\nA NKE-RTK-án lévő hallgatók egyéni rekordjai Iván Viktor 90s, Kiss Regina 74s', NULL),
|
||||||
|
(6, 'Fekvenyomás', '2015-ben a fekvenyomó világbajnokságot Smulter Fredrik finn súlyemelő 401 Kg-al nyerte.\r\nA súlyzó tömege nők esetében 25 kg, a férfiak esetében 60 kg a rúddal együtt. Az\r\nértékelésénél a szabályosan végrehajtott gyakorlatokat értékelik csak.\r\nA legtöbb pontért 25 gyakorlatot kell végezni mind a nőknek, mind a férfiaknak. A minimum:\r\negy gyakorlat mindkét nem esetében.', NULL),
|
||||||
|
(7, '4x10m-es ingafutás', 'A legjobb pontszámért 9,4 s illetve 8,8s alatt kell teljesíteni a nőknek, férfiaknak. A\r\ngyakorlat sikertelen 11,8 s illetve 11,2 s-on túl.', NULL),
|
||||||
|
(8, 'Helyből távolugrás', 'Byron Jones 2015-ben a 3,73 méteres ugrásával érte el a világcsúcsot.\r\nA nőknek 220 cm-re, a férfiak 250 cm-re kell ugraniuk a maximális pontért. A\r\nminimális távolság 172cm illetve 198 cm.', NULL),
|
||||||
|
(9, 'Felülés hanyattfekvésből', 'Az NKE-RTK hallgatói közül Papp Zsófia 66 db-ot, Gál Valentin 80\r\ndb-ot csinált 1 perc leforgása alatt.\r\nElső ütemre megtörténik a felülés, ami akkor szabályos, ha valamelyik könyök érinti a\r\ntérdet. Második ütemre vissza kell térni a kiinduló helyzetbe. A maximális pont eléréséhez 1\r\nperc alatt 45 illetve 55 ismétlést kell végezni a nőknek illetve a férfiaknak. A minimumhoz 7\r\nés 25 ismétlés szükséges.', NULL),
|
||||||
|
(10, 'Felülés hajlított térddel', 'Magyar Honvédség: A kiinduló helyzet hajlított ülés, ennek során a sarkak a talajon, a térd 90 fokban meghajlítva\r\nvan.\r\nA gyakorlat végrehajtására két perc áll rendelkezésre. Ennek során csak a szabályosan,\r\na fentiekben leírt módon végrehajtott gyakorlat értékelhető. Férfiaknál, nőknél egyaránt 90\r\ngyakorlatot kell végrehajtani a maximális pontért. Amennyiben a megadott időkeret alatt nem\r\nsikerül legalább 25 szabályos gyakorlatot végrehajtani, úgy az sikertelennek minősül.', NULL),
|
||||||
|
(11, 'Síkfutás 2000m', 'A maximálisan megszerezhető pontot az a felvételiző gyűjtheti be, aki a távot nők\r\nesetében 10:00 perc alatt, férfiak esetében 7:35 perc alatt teljesíti. A gyakorlat sikeres\r\nteljesítésére nők esetében maximum 16:00 perc, férfiak esetében 13:30 perc áll rendelkezésre.', NULL);
|
||||||
|
/*!40000 ALTER TABLE `exercise_type` ENABLE KEYS */;
|
||||||
|
|
||||||
|
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
|
||||||
|
/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
|
||||||
|
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
55
data/db/update_0_0_2.sql
Normal file
55
data/db/update_0_0_2.sql
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
ALTER TABLE `exercises`
|
||||||
|
ADD COLUMN `unit` ENUM('kg','meter','repeat','minute') NULL DEFAULT 'repeat' AFTER `quantity`,
|
||||||
|
CHANGE COLUMN `quantity` `quantity` FLOAT NULL DEFAULT NULL AFTER `datetime_exercise`;
|
||||||
|
|
||||||
|
ALTER TABLE `exercises`
|
||||||
|
CHANGE COLUMN `datetime_exercise` `date_add` DATETIME NOT NULL AFTER `customer_id`,
|
||||||
|
ADD INDEX `customer_id` (`customer_id`);
|
||||||
|
|
||||||
|
ALTER TABLE `customer`
|
||||||
|
ADD COLUMN `password` CHAR(100) NULL DEFAULT NULL AFTER `email`,
|
||||||
|
ADD COLUMN `date_add` DATETIME NULL AFTER `active`,
|
||||||
|
ADD COLUMN `date_change` DATETIME NULL AFTER `date_add`,
|
||||||
|
ADD COLUMN `data_policy_allowed` TINYINT NULL DEFAULT '1' AFTER `date_change`,
|
||||||
|
ADD COLUMN `admin` TINYINT NULL DEFAULT '0' AFTER `data_policy_allowed`;
|
||||||
|
|
||||||
|
CREATE TABLE `exercise_evaluation` (
|
||||||
|
`evaluation_id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`age_min` INT(11) NULL DEFAULT '0',
|
||||||
|
`age_max` INT(11) NULL DEFAULT '0',
|
||||||
|
`value_min` INT(11) NULL DEFAULT '0',
|
||||||
|
`value_max` INT(11) NULL DEFAULT '0',
|
||||||
|
`sex` ENUM('m','w') NOT NULL DEFAULT 'm' COLLATE 'utf8_hungarian_ci',
|
||||||
|
`evaluation` ENUM('excellent','very good','good','average','weak','poor') NOT NULL DEFAULT 'average' COLLATE 'utf8_hungarian_ci',
|
||||||
|
`description` TEXT(65535) NULL DEFAULT NULL COLLATE 'utf8_hungarian_ci',
|
||||||
|
PRIMARY KEY (`evaluation_id`) USING BTREE,
|
||||||
|
INDEX `value_min_value_max` (`value_min`, `value_max`) USING BTREE,
|
||||||
|
INDEX `age_min_age_max` (`age_min`, `age_max`) USING BTREE,
|
||||||
|
INDEX `age_min_age_max_value_min_value_max` (`age_min`, `age_max`, `value_min`, `value_max`) USING BTREE
|
||||||
|
)
|
||||||
|
COLLATE='utf8_hungarian_ci'
|
||||||
|
ENGINE=InnoDB
|
||||||
|
;
|
||||||
|
|
||||||
|
CREATE TABLE `customer_information` (
|
||||||
|
`customer_information_id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`title` CHAR(50) NULL DEFAULT '' COLLATE 'utf8_hungarian_ci',
|
||||||
|
`description` TEXT(65535) NULL DEFAULT NULL COLLATE 'utf8_hungarian_ci',
|
||||||
|
`date_add` DATETIME NULL DEFAULT NULL,
|
||||||
|
`display_begin` DATETIME NULL DEFAULT NULL,
|
||||||
|
`display_end` DATETIME NULL DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`customer_information_id`) USING BTREE,
|
||||||
|
INDEX `title` (`title`) USING BTREE
|
||||||
|
)
|
||||||
|
COLLATE='utf8_hungarian_ci'
|
||||||
|
ENGINE=InnoDB
|
||||||
|
;
|
||||||
|
|
||||||
|
INSERT INTO `customer_information` (`customer_information_id`, `title`, `description`, `date_add`, `display_begin`, `display_end`) VALUES (1, 'Fekvőtámasz világcsúcs', 'Világcsúcs fekvőtámasz: KJ Joseph 1 perc alatt 82 szabályos fekvőtámaszt végzett', '2020-06-01 08:00:00', '2020-06-01 08:00:00', '2023-07-01 08:00:00');
|
||||||
|
INSERT INTO `customer_information` (`customer_information_id`, `title`, `description`, `date_add`, `display_begin`, `display_end`) VALUES (2, 'Húzódszkodás csúcs', '24 órás csúcstartója Joonas Mäkipelto 5050 gyakorlattal', '2020-06-01 08:00:00', '2020-06-01 08:00:00', '2023-07-01 08:00:00');
|
||||||
|
INSERT INTO `customer_information` (`customer_information_id`, `title`, `description`, `date_add`, `display_begin`, `display_end`) VALUES (3, 'Fekvenyomás', '2015-ben a fekvenyomó világbajnokságot Smulter Fredrik finn súlyemelő 401 Kg-al nyerte', '2020-06-01 08:00:00', '2020-05-01 00:00:00', '2020-06-01 08:00:01');
|
||||||
|
|
||||||
|
DROP TABLE exercise_ages;
|
||||||
|
|
||||||
|
UPDATE configuration set config_value = "0.0.2" WHERE config_key = "db_version";
|
||||||
|
|
1
data/db/update_0_0_3.sql
Normal file
1
data/db/update_0_0_3.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
INSERT INTO `customer` (`name`, `firstname`, `email`, `password`, `sex`, `age`, `active`, `date_add`, `date_change`, `data_policy_allowed`, `admin`) VALUES ('Dummy User', NULL, 'bosi', '$2a$10$thOc8jS750c7xe9U9Qq3GuSPs/H0Pt2Ads05yzUlyzQBIj.Rk9QCy', 'm', 40, 'N', NULL, NULL, 1, 1);
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.4-bin.zip
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
183
gradlew
vendored
Executable file
183
gradlew
vendored
Executable file
@ -0,0 +1,183 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright 2015 the original author or authors.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn () {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die () {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
nonstop=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
NONSTOP* )
|
||||||
|
nonstop=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
|
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=`expr $i + 1`
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
0) set -- ;;
|
||||||
|
1) set -- "$args0" ;;
|
||||||
|
2) set -- "$args0" "$args1" ;;
|
||||||
|
3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Escape application args
|
||||||
|
save () {
|
||||||
|
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||||
|
echo " "
|
||||||
|
}
|
||||||
|
APP_ARGS=`save "$@"`
|
||||||
|
|
||||||
|
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||||
|
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||||
|
|
||||||
|
exec "$JAVACMD" "$@"
|
102
gradlew.bat
vendored
Normal file
102
gradlew.bat
vendored
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
@rem
|
||||||
|
@rem Copyright 2015 the original author or authors.
|
||||||
|
@rem
|
||||||
|
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@rem you may not use this file except in compliance with the License.
|
||||||
|
@rem You may obtain a copy of the License at
|
||||||
|
@rem
|
||||||
|
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@rem
|
||||||
|
@rem Unless required by applicable law or agreed to in writing, software
|
||||||
|
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@rem See the License for the specific language governing permissions and
|
||||||
|
@rem limitations under the License.
|
||||||
|
@rem
|
||||||
|
|
||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||||
|
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:init
|
||||||
|
@rem Get command-line arguments, handling Windows variants
|
||||||
|
|
||||||
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
|
||||||
|
:win9xME_args
|
||||||
|
@rem Slurp the command line arguments.
|
||||||
|
set CMD_LINE_ARGS=
|
||||||
|
set _SKIP=2
|
||||||
|
|
||||||
|
:win9xME_args_slurp
|
||||||
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
|
set CMD_LINE_ARGS=%*
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
13
readme.MD
Normal file
13
readme.MD
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#aitrainer server API v0.0.5
|
||||||
|
|
||||||
|
connects the MYSQL Database
|
||||||
|
provide a RESTful API for the mobile app
|
||||||
|
|
||||||
|
##finished API
|
||||||
|
|
||||||
|
* customers
|
||||||
|
* exercise_type
|
||||||
|
* exercise
|
||||||
|
* customer_information
|
||||||
|
|
||||||
|
with automatic database update
|
2
settings.gradle
Normal file
2
settings.gradle
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
include ':src'
|
||||||
|
include ':data'
|
21
src/main/kotlin/com/aitrainer/api/ApiApplication.kt
Normal file
21
src/main/kotlin/com/aitrainer/api/ApiApplication.kt
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package com.aitrainer.api
|
||||||
|
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.boot.SpringApplication
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||||
|
import org.springframework.boot.builder.SpringApplicationBuilder
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
class ApiApplication
|
||||||
|
private val logger = LoggerFactory.getLogger(ApiApplication::class.simpleName)
|
||||||
|
|
||||||
|
@Override
|
||||||
|
fun configure(application: SpringApplicationBuilder): SpringApplicationBuilder {
|
||||||
|
return application.sources(ApiApplication::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
logger.info(" ---- Start aitrainer API")
|
||||||
|
SpringApplication.run(ApiApplication::class.java, *args)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
|||||||
|
package com.aitrainer.api.controller
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
|
import org.springframework.web.bind.annotation.RestController
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping
|
||||||
|
class ApplicationProperties {
|
||||||
|
|
||||||
|
@Value("\${application.version}")
|
||||||
|
private lateinit var version: String
|
||||||
|
|
||||||
|
@Value("\${spring.datasource.url}")
|
||||||
|
private lateinit var datasourceUrl: String
|
||||||
|
|
||||||
|
@Value("\${spring.datasource.username}")
|
||||||
|
private lateinit var datasourceUsername: String
|
||||||
|
|
||||||
|
@Value("\${spring.datasource.password}")
|
||||||
|
private lateinit var datasourcePassword: String
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@GetMapping("/version")
|
||||||
|
fun getVersion(): String {
|
||||||
|
return this.version
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/datasourceUrl")
|
||||||
|
fun getDatasourceUrl(): String {
|
||||||
|
return this.datasourceUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/datasourceUsername")
|
||||||
|
fun getDatasourceUsername(): String {
|
||||||
|
return this.datasourceUsername
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/datasourcePassword")
|
||||||
|
fun getDatasourcePassword(): String {
|
||||||
|
return this.datasourcePassword
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.aitrainer.api.controller
|
||||||
|
|
||||||
|
import com.aitrainer.api.model.Configuration
|
||||||
|
|
||||||
|
import com.aitrainer.api.repository.ConfigurationRepository
|
||||||
|
import org.springframework.web.bind.annotation.RestController
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
class ConfigurationController ( private val configurationRepository: ConfigurationRepository) {
|
||||||
|
|
||||||
|
fun getConfiguration(key: String): Configuration =
|
||||||
|
configurationRepository.findByConfigKey(key)
|
||||||
|
|
||||||
|
fun updateConfiguration( newConfiguration: Configuration): Configuration {
|
||||||
|
val existingConfiguration: Configuration = configurationRepository.findByConfigKey(newConfiguration.configKey)
|
||||||
|
val updatedConfiguration: Configuration = existingConfiguration.copy(
|
||||||
|
configKey = newConfiguration.configKey,
|
||||||
|
configValue = newConfiguration.configValue,
|
||||||
|
//dateAdd = newConfiguration.dateAdd,
|
||||||
|
dateChange = LocalDateTime.now().toString())
|
||||||
|
|
||||||
|
configurationRepository.save(updatedConfiguration)
|
||||||
|
return existingConfiguration
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,116 @@
|
|||||||
|
package com.aitrainer.api.controller
|
||||||
|
|
||||||
|
import com.aitrainer.api.model.Customer
|
||||||
|
import com.aitrainer.api.model.User
|
||||||
|
import com.aitrainer.api.service.ServiceBeans
|
||||||
|
import com.aitrainer.api.repository.CustomerRepository
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.http.HttpHeaders
|
||||||
|
import org.springframework.http.ResponseEntity
|
||||||
|
import org.springframework.security.access.annotation.Secured
|
||||||
|
import org.springframework.web.bind.annotation.*
|
||||||
|
import javax.validation.Valid
|
||||||
|
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api")
|
||||||
|
class CustomerController ( private val customerRepository: CustomerRepository ) {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
var serviceBeans: ServiceBeans? = null
|
||||||
|
|
||||||
|
@Secured
|
||||||
|
@GetMapping("/customers")
|
||||||
|
fun getAllCustomers(@RequestHeader headers: HttpHeaders): List<Customer> =
|
||||||
|
customerRepository.findAll()
|
||||||
|
|
||||||
|
@Secured
|
||||||
|
@PostMapping("/customers")
|
||||||
|
fun createNewCustomer(@Valid @RequestBody customer: Customer, @RequestHeader headers: HttpHeaders): Customer =
|
||||||
|
customerRepository.save(customer)
|
||||||
|
|
||||||
|
@Secured
|
||||||
|
@GetMapping("/customers/{id}")
|
||||||
|
fun getCustomerById(@PathVariable(value = "id") customerId: Long, @RequestHeader headers: HttpHeaders): ResponseEntity<Customer> {
|
||||||
|
return customerRepository.findById(customerId).map { customer ->
|
||||||
|
ResponseEntity.ok(customer)
|
||||||
|
}.orElse(ResponseEntity.notFound().build())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Secured
|
||||||
|
@GetMapping("/customers/real")
|
||||||
|
fun getRealCustomers(active: String, @RequestHeader headers: HttpHeaders): List<Customer> =
|
||||||
|
customerRepository.findByActive(active)
|
||||||
|
|
||||||
|
@Secured
|
||||||
|
@PutMapping("/customers/{id}")
|
||||||
|
fun updateCustomerById(@PathVariable(value = "id") customerId: Long,
|
||||||
|
@Valid @RequestBody newCustomer: Customer,
|
||||||
|
@RequestHeader headers: HttpHeaders): ResponseEntity<Customer> {
|
||||||
|
|
||||||
|
return customerRepository.findById(customerId).map { existingCustomer ->
|
||||||
|
val updatedCustomer: Customer = existingCustomer
|
||||||
|
.copy(name = newCustomer.name,
|
||||||
|
firstname = newCustomer.firstname,
|
||||||
|
sex = newCustomer.sex,
|
||||||
|
age = newCustomer.age)
|
||||||
|
ResponseEntity.ok().body(customerRepository.save(updatedCustomer))
|
||||||
|
}.orElse(ResponseEntity.notFound().build())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping("/registration")
|
||||||
|
fun registration(@Valid @RequestBody json: String): ResponseEntity<*> {
|
||||||
|
val customer = Customer()
|
||||||
|
|
||||||
|
val newUser: User = User().fromJson(json)
|
||||||
|
with (customer) {
|
||||||
|
email = newUser.username
|
||||||
|
password = serviceBeans!!.passwordEncoder().encode(newUser.password)
|
||||||
|
}
|
||||||
|
|
||||||
|
val returnCustomer: Customer? = customerRepository.findByEmail(newUser.username).let {
|
||||||
|
if ( it == null) {
|
||||||
|
customerRepository.save(customer)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return if ( returnCustomer != null ) {
|
||||||
|
ResponseEntity.ok().body(returnCustomer)
|
||||||
|
} else {
|
||||||
|
ResponseEntity.badRequest().body("Customer exists")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/login")
|
||||||
|
fun login(@Valid @RequestBody json: String): ResponseEntity<*> {
|
||||||
|
val customer = Customer()
|
||||||
|
|
||||||
|
val newUser: User = User().fromJson(json)
|
||||||
|
with (customer) {
|
||||||
|
email = newUser.username
|
||||||
|
password = newUser.password
|
||||||
|
}
|
||||||
|
val returnCustomer: Customer? = customerRepository.findByEmail(newUser.username).let {
|
||||||
|
if ( it == null) {
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
if (serviceBeans!!.passwordEncoder().matches(newUser.password, it.password)) {
|
||||||
|
it
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return if ( returnCustomer != null ) {
|
||||||
|
ResponseEntity.ok().body(returnCustomer)
|
||||||
|
} else {
|
||||||
|
ResponseEntity.badRequest().body("Customer does not exist or the password is wrong")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package com.aitrainer.api.controller
|
||||||
|
|
||||||
|
import com.aitrainer.api.ApiApplication
|
||||||
|
import com.aitrainer.api.repository.ConfigurationRepository
|
||||||
|
import org.aspectj.lang.JoinPoint
|
||||||
|
import org.aspectj.lang.annotation.Aspect
|
||||||
|
import org.aspectj.lang.annotation.Before
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
@Aspect
|
||||||
|
@Component
|
||||||
|
class CustomerControllerAspect {
|
||||||
|
private val logger = LoggerFactory.getLogger(ApiApplication::class.simpleName)
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private lateinit var configurationRepository: ConfigurationRepository
|
||||||
|
@Autowired
|
||||||
|
private lateinit var properties: ApplicationProperties
|
||||||
|
|
||||||
|
@Before("execution(* com.aitrainer.api.controller.CustomerController.*(..))")
|
||||||
|
fun customerControllerAspect(joinPoint: JoinPoint) {
|
||||||
|
println("customer controller")
|
||||||
|
Singleton.checkDBUpdate(configurationRepository, properties)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
|||||||
|
package com.aitrainer.api.controller
|
||||||
|
|
||||||
|
import com.aitrainer.api.model.CustomerInformation
|
||||||
|
import com.aitrainer.api.repository.CustomerInformationRepository
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
|
import org.springframework.web.bind.annotation.RestController
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api")
|
||||||
|
class CustomerInformationController( private val customerInformationRepository: CustomerInformationRepository ) {
|
||||||
|
|
||||||
|
@GetMapping("/customer_information")
|
||||||
|
fun getCustomerInformation(): List<CustomerInformation> {
|
||||||
|
val dateTime: String = LocalDateTime.now().toString()
|
||||||
|
return customerInformationRepository.findByDisplayBeginLessThanAndDisplayEndGreaterThan(dateTime, dateTime )
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package com.aitrainer.api.controller
|
||||||
|
|
||||||
|
import com.aitrainer.api.ApiApplication
|
||||||
|
import com.aitrainer.api.repository.ConfigurationRepository
|
||||||
|
import org.aspectj.lang.annotation.Aspect
|
||||||
|
import org.aspectj.lang.annotation.Before
|
||||||
|
import org.aspectj.lang.annotation.Pointcut
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
|
||||||
|
@Aspect
|
||||||
|
@Component
|
||||||
|
@Suppress("unused")
|
||||||
|
class CustomerInformationControllerAspect {
|
||||||
|
private val logger = LoggerFactory.getLogger(ApiApplication::class.simpleName)
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private lateinit var configurationRepository: ConfigurationRepository
|
||||||
|
@Autowired
|
||||||
|
private lateinit var properties: ApplicationProperties
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
@Pointcut("execution(* com.aitrainer.api.controller.CustomerInformationController.*())")
|
||||||
|
fun customerInformationAspect() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
@Before("customerInformationAspect()")
|
||||||
|
fun dbCheckAop() {
|
||||||
|
Singleton.checkDBUpdate(configurationRepository, properties)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,102 @@
|
|||||||
|
package com.aitrainer.api.controller
|
||||||
|
|
||||||
|
import com.aitrainer.api.ApiApplication
|
||||||
|
import com.aitrainer.api.model.Configuration
|
||||||
|
import com.aitrainer.api.repository.ConfigurationRepository
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.web.bind.annotation.RestController
|
||||||
|
import java.io.File
|
||||||
|
import java.sql.Connection
|
||||||
|
import java.sql.DriverManager
|
||||||
|
import java.sql.ResultSet
|
||||||
|
import java.util.Properties
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
object Singleton {
|
||||||
|
|
||||||
|
private lateinit var connection: Connection
|
||||||
|
private lateinit var configurationRepository: ConfigurationRepository
|
||||||
|
private lateinit var properties: ApplicationProperties
|
||||||
|
|
||||||
|
private var initialized: Boolean = false
|
||||||
|
|
||||||
|
private val logger = LoggerFactory.getLogger(ApiApplication::class.simpleName)
|
||||||
|
|
||||||
|
// to use the singleton functionality avoiding the db access before each request
|
||||||
|
private var dbVersion: String = ""
|
||||||
|
private var appVersion: String = ""
|
||||||
|
|
||||||
|
fun checkDBUpdate(configurationRepository: ConfigurationRepository, properties: ApplicationProperties) {
|
||||||
|
|
||||||
|
if ( dbVersion.isNotEmpty() && appVersion.isNotEmpty()) {
|
||||||
|
// no db access
|
||||||
|
//println("DB up-to-date, no DB access")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.configurationRepository = configurationRepository
|
||||||
|
this.properties = properties
|
||||||
|
|
||||||
|
val dbConfig: Configuration = configurationRepository.findByConfigKey("db_version")
|
||||||
|
val applicationVersion: String = properties.getVersion()
|
||||||
|
|
||||||
|
this.dbVersion = dbConfig.configValue
|
||||||
|
this.appVersion = applicationVersion
|
||||||
|
|
||||||
|
if ( dbConfig.configValue != applicationVersion ) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
|
||||||
|
val versionNumber: String = applicationVersion.replace(".", "_")
|
||||||
|
val fileName = "update_$versionNumber.sql"
|
||||||
|
val path = "./data/db/"
|
||||||
|
val file2Update = path+fileName
|
||||||
|
|
||||||
|
var sqlRows = ""
|
||||||
|
File(file2Update).forEachLine {
|
||||||
|
sqlRows += it
|
||||||
|
if ( sqlRows.contains(";") ) {
|
||||||
|
execSQL(sqlRows)
|
||||||
|
sqlRows = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.connection.commit()
|
||||||
|
logger.info("Database has been updated to $applicationVersion" )
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
logger.info("Database exception of $applicationVersion: " + exception.message )
|
||||||
|
this.connection.rollback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun execSQL( sql: String ) {
|
||||||
|
if (! this.initialized ) {
|
||||||
|
this.getConnection()
|
||||||
|
}
|
||||||
|
|
||||||
|
with(this.connection) {
|
||||||
|
createStatement().execute(sql)
|
||||||
|
//commit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun execQuery( sql: String ): ResultSet {
|
||||||
|
if (! this.initialized ) {
|
||||||
|
this.getConnection()
|
||||||
|
}
|
||||||
|
|
||||||
|
return connection.createStatement().executeQuery(sql)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getConnection(): Connection {
|
||||||
|
val connectionProps = Properties()
|
||||||
|
connectionProps["user"] = this.properties.getDatasourceUsername()
|
||||||
|
connectionProps["password"] = this.properties.getDatasourcePassword()
|
||||||
|
this.connection = DriverManager.getConnection(this.properties.getDatasourceUrl(), connectionProps)
|
||||||
|
this.connection.autoCommit = false
|
||||||
|
this.initialized = true
|
||||||
|
return this.connection
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package com.aitrainer.api.controller
|
||||||
|
|
||||||
|
import com.aitrainer.api.model.Exercises
|
||||||
|
import com.aitrainer.api.repository.ExercisesRepository
|
||||||
|
import org.springframework.http.ResponseEntity
|
||||||
|
import org.springframework.web.bind.annotation.*
|
||||||
|
import javax.validation.Valid
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api")
|
||||||
|
class ExerciseController(private val exercisesRepository: ExercisesRepository) {
|
||||||
|
|
||||||
|
@GetMapping("/exercises/{id}")
|
||||||
|
fun getExerciseById(@PathVariable(value = "id") exerciseId: Long): ResponseEntity<Exercises> {
|
||||||
|
return exercisesRepository.findById(exerciseId).map { exercise ->
|
||||||
|
ResponseEntity.ok(exercise)
|
||||||
|
}.orElse(ResponseEntity.notFound().build())
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/exercises/customer/{id}")
|
||||||
|
fun getAllExersicesByCustomerId(@PathVariable( value = "id" ) customerId: Long? ): List<Exercises> =
|
||||||
|
exercisesRepository.getAllByCustomerId(customerId)
|
||||||
|
|
||||||
|
@PostMapping("/exercises")
|
||||||
|
fun createNewExercise(@Valid @RequestBody exercise: Exercises): Exercises {
|
||||||
|
return exercisesRepository.save(exercise)
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/exercises/{id}")
|
||||||
|
fun updateExerciseById(@PathVariable(value = "id") exerciseId: Long,
|
||||||
|
@Valid @RequestBody newExercises: Exercises): ResponseEntity<Exercises> {
|
||||||
|
return exercisesRepository.findById(exerciseId).map { existingExercises ->
|
||||||
|
val updatedExercises: Exercises = existingExercises.copy(
|
||||||
|
exerciseTypeId = newExercises.exerciseTypeId,
|
||||||
|
customerId = newExercises.customerId,
|
||||||
|
dateAdd = newExercises.dateAdd,
|
||||||
|
quantity = newExercises.quantity,
|
||||||
|
restTime = newExercises.restTime
|
||||||
|
)
|
||||||
|
ResponseEntity.ok().body(exercisesRepository.save(updatedExercises))
|
||||||
|
}.orElse(ResponseEntity.notFound().build())
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package com.aitrainer.api.controller
|
||||||
|
|
||||||
|
import com.aitrainer.api.ApiApplication
|
||||||
|
import com.aitrainer.api.repository.ConfigurationRepository
|
||||||
|
import org.aspectj.lang.annotation.Aspect
|
||||||
|
import org.aspectj.lang.annotation.Before
|
||||||
|
import org.aspectj.lang.annotation.Pointcut
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Suppress("unused")
|
||||||
|
@Aspect
|
||||||
|
class ExerciseControllerAspect {
|
||||||
|
|
||||||
|
private val logger = LoggerFactory.getLogger(ApiApplication::class.simpleName)
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private lateinit var configurationRepository: ConfigurationRepository
|
||||||
|
@Autowired
|
||||||
|
private lateinit var properties: ApplicationProperties
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
@Pointcut("execution(* com.aitrainer.api.controller.ExerciseController.*())")
|
||||||
|
fun exerciseControllerAspect() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before("exerciseControllerAspect()")
|
||||||
|
fun loggingAop() {
|
||||||
|
Singleton.checkDBUpdate(configurationRepository, properties)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
package com.aitrainer.api.controller
|
||||||
|
|
||||||
|
import com.aitrainer.api.model.ExerciseType
|
||||||
|
import com.aitrainer.api.repository.ExerciseTypeRepository
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
|
||||||
|
import org.springframework.http.ResponseEntity
|
||||||
|
import org.springframework.web.bind.annotation.*
|
||||||
|
import javax.validation.Valid
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api")
|
||||||
|
class ExerciseTypeController ( private val exerciseTypeRepository: ExerciseTypeRepository ) {
|
||||||
|
private val logger = LoggerFactory.getLogger(javaClass)
|
||||||
|
|
||||||
|
@GetMapping("/exercise_type")
|
||||||
|
fun getAllExerciseType(): List<ExerciseType> {
|
||||||
|
val list: List<ExerciseType> = exerciseTypeRepository.findAll()
|
||||||
|
logger.info(" -- Get All exercise types..")
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping("/exercise_type")
|
||||||
|
fun createNewExerciseType(@Valid @RequestBody exerciseType: ExerciseType): ExerciseType {
|
||||||
|
logger.info("Create new exercise type: $exerciseType")
|
||||||
|
return exerciseTypeRepository.save(exerciseType)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@GetMapping("/exercise_type/{id}")
|
||||||
|
fun getExerciseTypeById(@PathVariable(value = "id") exerciseTypeId: Long): ResponseEntity<ExerciseType> {
|
||||||
|
logger.info("Get exercise type by id: $exerciseTypeId")
|
||||||
|
return exerciseTypeRepository.findById(exerciseTypeId).map { exerciseType ->
|
||||||
|
ResponseEntity.ok(exerciseType)
|
||||||
|
}.orElse(ResponseEntity.notFound().build())
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
@GetMapping("/exercise_type/name/{name}")
|
||||||
|
fun getExerciseTypeByName(@PathVariable(value = "name") name: String): ResponseEntity<ExerciseType> {
|
||||||
|
return exerciseTypeRepository.findByName(name).map { exerciseType ->
|
||||||
|
ResponseEntity.ok(exerciseType)
|
||||||
|
}.orElse(ResponseEntity.notFound().build())
|
||||||
|
}*/
|
||||||
|
|
||||||
|
@PostMapping("/exercise_type/{id}")
|
||||||
|
fun updateExerciseTypesById(@PathVariable(value = "id") exerciseTypeId: Long,
|
||||||
|
@Valid @RequestBody newExerciseType: ExerciseType): ResponseEntity<ExerciseType> {
|
||||||
|
logger.info("Update exercise type by id: $exerciseTypeId with object $newExerciseType")
|
||||||
|
return exerciseTypeRepository.findById(exerciseTypeId).map { existingExerciseType ->
|
||||||
|
val updatedExerciseType: ExerciseType = existingExerciseType
|
||||||
|
.copy(name = newExerciseType.name,
|
||||||
|
description = newExerciseType.description,
|
||||||
|
video = newExerciseType.video)
|
||||||
|
ResponseEntity.ok().body(exerciseTypeRepository.save(updatedExerciseType))
|
||||||
|
}.orElse(ResponseEntity.notFound().build())
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package com.aitrainer.api.controller
|
||||||
|
|
||||||
|
import com.aitrainer.api.ApiApplication
|
||||||
|
import com.aitrainer.api.repository.ConfigurationRepository
|
||||||
|
import org.aspectj.lang.annotation.Aspect
|
||||||
|
import org.aspectj.lang.annotation.Before
|
||||||
|
import org.aspectj.lang.annotation.Pointcut
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
@Aspect
|
||||||
|
@Component
|
||||||
|
class ExerciseTypeControllerAspect {
|
||||||
|
private val logger = LoggerFactory.getLogger(ApiApplication::class.simpleName)
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private lateinit var configurationRepository: ConfigurationRepository
|
||||||
|
@Autowired
|
||||||
|
private lateinit var properties: ApplicationProperties
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
@Pointcut("execution(* com.aitrainer.api.controller.ExerciseTypeController.*())")
|
||||||
|
fun exerciseTypeControllerAspect() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before("exerciseTypeControllerAspect()")
|
||||||
|
fun loggingAop() {
|
||||||
|
Singleton.checkDBUpdate(configurationRepository, properties)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
20
src/main/kotlin/com/aitrainer/api/model/Configuration.kt
Normal file
20
src/main/kotlin/com/aitrainer/api/model/Configuration.kt
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package com.aitrainer.api.model
|
||||||
|
|
||||||
|
import javax.persistence.Entity
|
||||||
|
import javax.persistence.GeneratedValue
|
||||||
|
import javax.persistence.GenerationType
|
||||||
|
import javax.persistence.Id
|
||||||
|
import javax.validation.constraints.NotBlank
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
data class Configuration (
|
||||||
|
|
||||||
|
|
||||||
|
@get: NotBlank var configKey: String = "",
|
||||||
|
@get: NotBlank var configValue: String = "",
|
||||||
|
var dateAdd: String,
|
||||||
|
var dateChange: String = "",
|
||||||
|
|
||||||
|
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
val configuration_id: Long = 0
|
||||||
|
)
|
24
src/main/kotlin/com/aitrainer/api/model/Customer.kt
Normal file
24
src/main/kotlin/com/aitrainer/api/model/Customer.kt
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package com.aitrainer.api.model
|
||||||
|
|
||||||
|
import javax.persistence.Entity
|
||||||
|
import javax.persistence.GeneratedValue
|
||||||
|
import javax.persistence.GenerationType
|
||||||
|
import javax.persistence.Id
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
data class Customer (
|
||||||
|
var name: String = "",
|
||||||
|
var firstname: String = "",
|
||||||
|
var email: String = "",
|
||||||
|
var age: Int = 0,
|
||||||
|
var sex: String = "m",
|
||||||
|
var active: String = "N",
|
||||||
|
var dateAdd: String? = null,
|
||||||
|
var dateChange: String? = null,
|
||||||
|
var dataPolicyAllowed: Int = 0,
|
||||||
|
var admin: Int = 0,
|
||||||
|
var password: String = "",
|
||||||
|
|
||||||
|
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
val customer_id: Long = 0
|
||||||
|
)
|
@ -0,0 +1,21 @@
|
|||||||
|
package com.aitrainer.api.model
|
||||||
|
|
||||||
|
import javax.persistence.Entity
|
||||||
|
import javax.persistence.GeneratedValue
|
||||||
|
import javax.persistence.GenerationType
|
||||||
|
import javax.persistence.Id
|
||||||
|
import javax.validation.constraints.NotBlank
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
class CustomerInformation (
|
||||||
|
@get: NotBlank var title: String = "",
|
||||||
|
var description: String = "",
|
||||||
|
|
||||||
|
var dateAdd: String? = null,
|
||||||
|
var displayBegin: String? = null,
|
||||||
|
var displayEnd: String? = null,
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
val customerInformationId: Long = 0
|
||||||
|
)
|
21
src/main/kotlin/com/aitrainer/api/model/ExerciseType.kt
Normal file
21
src/main/kotlin/com/aitrainer/api/model/ExerciseType.kt
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package com.aitrainer.api.model
|
||||||
|
|
||||||
|
import org.hibernate.type.BinaryType
|
||||||
|
import javax.persistence.Entity
|
||||||
|
import javax.persistence.GeneratedValue
|
||||||
|
import javax.persistence.GenerationType
|
||||||
|
import javax.persistence.Id
|
||||||
|
import javax.validation.constraints.NotBlank
|
||||||
|
import javax.validation.constraints.Null
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
data class ExerciseType (
|
||||||
|
|
||||||
|
@get: NotBlank var name: String = "",
|
||||||
|
@get: NotBlank var description: String = "",
|
||||||
|
@get: Null var video: BinaryType?,
|
||||||
|
|
||||||
|
|
||||||
|
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
val exerciseTypeId: Long = 0
|
||||||
|
)
|
21
src/main/kotlin/com/aitrainer/api/model/Exercises.kt
Normal file
21
src/main/kotlin/com/aitrainer/api/model/Exercises.kt
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package com.aitrainer.api.model
|
||||||
|
|
||||||
|
import org.springframework.lang.NonNull
|
||||||
|
import javax.persistence.Entity
|
||||||
|
import javax.persistence.GeneratedValue
|
||||||
|
import javax.persistence.GenerationType
|
||||||
|
import javax.persistence.Id
|
||||||
|
import javax.validation.constraints.Null
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
data class Exercises (
|
||||||
|
@get: NonNull var exerciseTypeId: Long = 0,
|
||||||
|
@get: NonNull var customerId: Long = 0,
|
||||||
|
@get: NonNull var dateAdd: String? = null,
|
||||||
|
@get: NonNull var quantity: Int = 0,
|
||||||
|
@get: Null var restTime: Int?, // in seconds
|
||||||
|
@get: NonNull var unit: String? = null,
|
||||||
|
|
||||||
|
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
val exerciseId: Long = 0
|
||||||
|
)
|
15
src/main/kotlin/com/aitrainer/api/model/User.kt
Normal file
15
src/main/kotlin/com/aitrainer/api/model/User.kt
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package com.aitrainer.api.model
|
||||||
|
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
import kotlinx.serialization.json.*
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class User (
|
||||||
|
var username: String = "",
|
||||||
|
var password: String = ""
|
||||||
|
) {
|
||||||
|
@OptIn(UnstableDefault::class)
|
||||||
|
fun fromJson(json: String): User {
|
||||||
|
return Json.parse(serializer(), json)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.aitrainer.api.repository
|
||||||
|
|
||||||
|
import com.aitrainer.api.model.Configuration
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository
|
||||||
|
import org.springframework.stereotype.Repository
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
interface ConfigurationRepository : JpaRepository<Configuration, Long> {
|
||||||
|
fun findByConfigKey( key: String ):Configuration
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.aitrainer.api.repository
|
||||||
|
|
||||||
|
import com.aitrainer.api.model.CustomerInformation
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository
|
||||||
|
import org.springframework.stereotype.Repository
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
interface CustomerInformationRepository: JpaRepository<CustomerInformation, Long> {
|
||||||
|
fun findByDisplayBeginLessThanAndDisplayEndGreaterThan( dateTimeBegin: String, dateTimeEnd: String ):
|
||||||
|
List<CustomerInformation>
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.aitrainer.api.repository
|
||||||
|
|
||||||
|
import com.aitrainer.api.model.Customer
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository
|
||||||
|
import org.springframework.stereotype.Repository
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
interface CustomerRepository : JpaRepository<Customer, Long> {
|
||||||
|
fun findByActive( active: String? ): List<Customer>
|
||||||
|
|
||||||
|
fun findByEmail(email: String?): Customer?
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.aitrainer.api.repository
|
||||||
|
|
||||||
|
import com.aitrainer.api.model.ExerciseType
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository
|
||||||
|
import org.springframework.stereotype.Repository
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
interface ExerciseTypeRepository : JpaRepository<ExerciseType, Long>{
|
||||||
|
|
||||||
|
fun findByName(name: String): ExerciseType
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.aitrainer.api.repository
|
||||||
|
|
||||||
|
import com.aitrainer.api.model.Exercises
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository
|
||||||
|
import org.springframework.stereotype.Repository
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
interface ExercisesRepository : JpaRepository<Exercises, Long> {
|
||||||
|
fun getAllByCustomerId( customerId: Long? ):List<Exercises>
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.aitrainer.api.security
|
||||||
|
|
||||||
|
import com.aitrainer.api.ApiApplication
|
||||||
|
import com.aitrainer.api.controller.ApplicationProperties
|
||||||
|
import com.aitrainer.api.controller.Singleton
|
||||||
|
import com.aitrainer.api.repository.ConfigurationRepository
|
||||||
|
import org.aspectj.lang.JoinPoint
|
||||||
|
import org.aspectj.lang.annotation.Aspect
|
||||||
|
import org.aspectj.lang.annotation.Before
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
@Aspect
|
||||||
|
@Component
|
||||||
|
class AuthenticationControllerAspect {
|
||||||
|
private val logger = LoggerFactory.getLogger(ApiApplication::class.simpleName)
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private lateinit var configurationRepository: ConfigurationRepository
|
||||||
|
@Autowired
|
||||||
|
private lateinit var properties: ApplicationProperties
|
||||||
|
|
||||||
|
@Before("execution(* com.aitrainer.api.security.JwtAuthenticationController.*(..))")
|
||||||
|
fun customerControllerAspect(joinPoint: JoinPoint) {
|
||||||
|
println("auth controller join")
|
||||||
|
Singleton.checkDBUpdate(configurationRepository, properties)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
package com.aitrainer.api.security
|
||||||
|
|
||||||
|
import com.aitrainer.api.service.UserDetailsServiceImpl
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.http.ResponseEntity
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager
|
||||||
|
import org.springframework.security.authentication.BadCredentialsException
|
||||||
|
import org.springframework.security.authentication.DisabledException
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
|
||||||
|
import org.springframework.web.bind.annotation.*
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@RestController
|
||||||
|
//@CrossOrigin
|
||||||
|
@RequestMapping("/api")
|
||||||
|
class JwtAuthenticationController {
|
||||||
|
@Autowired
|
||||||
|
private val authenticationManager: AuthenticationManager? = null
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private val jwtTokenUtil: JwtTokenUtil? = null
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private val jwtUserDetailsService: UserDetailsServiceImpl? = null
|
||||||
|
|
||||||
|
@PostMapping("/authenticate")
|
||||||
|
fun generateAuthenticationToken(@RequestBody authenticationRequest: JwtRequest): ResponseEntity<*> {
|
||||||
|
|
||||||
|
authenticate(authenticationRequest.username!!, authenticationRequest.password!!)
|
||||||
|
|
||||||
|
val userDetails = jwtUserDetailsService
|
||||||
|
?.loadUserByUsername(authenticationRequest.username)
|
||||||
|
val token: String = jwtTokenUtil!!.generateToken(userDetails!!)
|
||||||
|
return ResponseEntity.ok<Any>(JwtResponse(token))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun authenticate(username: String, password: String) {
|
||||||
|
try {
|
||||||
|
authenticationManager!!.authenticate(UsernamePasswordAuthenticationToken(username, password))
|
||||||
|
} catch (e: DisabledException) {
|
||||||
|
throw Exception("USER_DISABLED", e)
|
||||||
|
} catch (e: BadCredentialsException) {
|
||||||
|
throw Exception("INVALID_CREDENTIALS", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.aitrainer.api.security
|
||||||
|
|
||||||
|
import org.springframework.security.web.AuthenticationEntryPoint
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
import java.io.IOException
|
||||||
|
import javax.servlet.http.HttpServletRequest
|
||||||
|
import javax.servlet.http.HttpServletResponse
|
||||||
|
import java.io.Serializable
|
||||||
|
import org.springframework.security.core.AuthenticationException
|
||||||
|
|
||||||
|
|
||||||
|
@Component
|
||||||
|
class JwtAuthenticationEntryPoint : AuthenticationEntryPoint, Serializable {
|
||||||
|
@Throws(IOException::class)
|
||||||
|
override fun commence(request: HttpServletRequest?, response: HttpServletResponse,
|
||||||
|
authException: AuthenticationException?) {
|
||||||
|
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized")
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val serialVersionUID = -7858869558953243875L
|
||||||
|
}
|
||||||
|
}
|
19
src/main/kotlin/com/aitrainer/api/security/JwtRequest.kt
Normal file
19
src/main/kotlin/com/aitrainer/api/security/JwtRequest.kt
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package com.aitrainer.api.security
|
||||||
|
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
|
|
||||||
|
class JwtRequest : Serializable {
|
||||||
|
var username: String? = null
|
||||||
|
var password: String? = null
|
||||||
|
|
||||||
|
//default constructor for JSON Parsing
|
||||||
|
constructor(username: String?, password: String?) {
|
||||||
|
this.username = username
|
||||||
|
this.password = password
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val serialVersionUID = 5926468583005150707L
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
package com.aitrainer.api.security
|
||||||
|
|
||||||
|
import com.aitrainer.api.service.UserDetailsServiceImpl
|
||||||
|
import io.jsonwebtoken.ExpiredJwtException
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails
|
||||||
|
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
import org.springframework.web.filter.OncePerRequestFilter
|
||||||
|
import java.io.IOException
|
||||||
|
import javax.servlet.FilterChain
|
||||||
|
import javax.servlet.ServletException
|
||||||
|
import javax.servlet.http.HttpServletRequest
|
||||||
|
import javax.servlet.http.HttpServletResponse
|
||||||
|
|
||||||
|
|
||||||
|
@Component
|
||||||
|
class JwtRequestFilter : OncePerRequestFilter() {
|
||||||
|
@Autowired
|
||||||
|
private val jwtUserDetailsService: UserDetailsServiceImpl? = null
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private val jwtTokenUtil: JwtTokenUtil? = null
|
||||||
|
|
||||||
|
//@Autowired
|
||||||
|
//private lateinit var authenticationController: JwtAuthenticationController
|
||||||
|
|
||||||
|
@Throws(ServletException::class, IOException::class)
|
||||||
|
override fun doFilterInternal(request: HttpServletRequest, response: HttpServletResponse, chain: FilterChain) {
|
||||||
|
val requestTokenHeader = request.getHeader("Authorization")
|
||||||
|
var username: String? = null
|
||||||
|
var jwtToken: String? = null
|
||||||
|
// JWT Token is in the form "Bearer token". Remove Bearer word and get only the Token
|
||||||
|
if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer")) {
|
||||||
|
jwtToken = requestTokenHeader.substring(7)
|
||||||
|
try {
|
||||||
|
username = jwtTokenUtil!!.getUsernameFromToken(jwtToken)
|
||||||
|
} catch (e: IllegalArgumentException) {
|
||||||
|
println("Unable to get JWT Token")
|
||||||
|
} catch (e: ExpiredJwtException) {
|
||||||
|
println("JWT Token has expired")
|
||||||
|
}
|
||||||
|
} else if (requestTokenHeader != null && requestTokenHeader.equals("1") ) {
|
||||||
|
logger.warn("Authenticate")
|
||||||
|
//val credentials: User = ObjectMapper().readValue(request.inputStream, User::class.java)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
logger.warn("JWT Token does not begin with Bearer String")
|
||||||
|
}
|
||||||
|
|
||||||
|
//Once we get the token validate it.
|
||||||
|
if (username != null && SecurityContextHolder.getContext().authentication == null) {
|
||||||
|
val userDetails: UserDetails = jwtUserDetailsService!!.loadUserByUsername(username)
|
||||||
|
|
||||||
|
// if token is valid configure Spring Security to manually set authentication
|
||||||
|
if (jwtTokenUtil!!.validateToken(jwtToken!!, userDetails)) {
|
||||||
|
val usernamePasswordAuthenticationToken = UsernamePasswordAuthenticationToken(
|
||||||
|
userDetails, null, userDetails.authorities)
|
||||||
|
usernamePasswordAuthenticationToken.details = WebAuthenticationDetailsSource().buildDetails(request)
|
||||||
|
// After setting the Authentication in the context, we specify
|
||||||
|
// that the current user is authenticated. So it passes the Spring Security Configurations successfully.
|
||||||
|
SecurityContextHolder.getContext().authentication = usernamePasswordAuthenticationToken
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chain.doFilter(request, response)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*private fun readUserCredentials(request: HttpServletRequest): UserCredentials? {
|
||||||
|
return try {
|
||||||
|
ObjectMapper().readValue(request.inputStream, UserCredentials::class.java)
|
||||||
|
} catch (ioe: IOException) {
|
||||||
|
throw BadCredentialsException("Invalid request", ioe)
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
12
src/main/kotlin/com/aitrainer/api/security/JwtResponse.kt
Normal file
12
src/main/kotlin/com/aitrainer/api/security/JwtResponse.kt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package com.aitrainer.api.security
|
||||||
|
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
|
|
||||||
|
class JwtResponse(val token: String) : Serializable {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val serialVersionUID = -8091879091924046844L
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
package com.aitrainer.api.security
|
||||||
|
|
||||||
|
import com.aitrainer.api.service.ServiceBeans
|
||||||
|
import com.aitrainer.api.service.UserDetailsServiceImpl
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.context.annotation.Bean
|
||||||
|
import org.springframework.context.annotation.Configuration
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager
|
||||||
|
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
|
||||||
|
import org.springframework.security.config.http.SessionCreationPolicy
|
||||||
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
|
||||||
|
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
|
class JwtSecurityConfig : WebSecurityConfigurerAdapter() {
|
||||||
|
@Autowired
|
||||||
|
private val jwtAuthenticationEntryPoint: JwtAuthenticationEntryPoint? = null
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private val jwtUserDetailsService: UserDetailsServiceImpl? = null
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private val jwtRequestFilter: JwtRequestFilter? = null
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private val serviceBeans: ServiceBeans? = null
|
||||||
|
|
||||||
|
override fun configure(auth: AuthenticationManagerBuilder?) {
|
||||||
|
auth!!.userDetailsService(jwtUserDetailsService).passwordEncoder(serviceBeans!!.passwordEncoder())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@Throws(Exception::class)
|
||||||
|
override fun authenticationManagerBean(): AuthenticationManager {
|
||||||
|
return super.authenticationManagerBean()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(Exception::class)
|
||||||
|
override fun configure(httpSecurity: HttpSecurity) {
|
||||||
|
|
||||||
|
// We don't need CSRF for this example
|
||||||
|
httpSecurity.
|
||||||
|
csrf().disable().
|
||||||
|
// dont authenticate this particular request
|
||||||
|
authorizeRequests().antMatchers("/api/authenticate").permitAll().
|
||||||
|
// all other requests need to be authenticated
|
||||||
|
anyRequest().authenticated().and().
|
||||||
|
// make sure we use stateless session; session won't be used to
|
||||||
|
// store user's state.
|
||||||
|
exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint).and().
|
||||||
|
// Add a filter to validate the tokens with every request
|
||||||
|
//addFilterAt(JwtAuthenticationFilter(authenticationManagerBean()), UsernamePasswordAuthenticationFilter::class.java).
|
||||||
|
addFilterAfter(jwtRequestFilter, UsernamePasswordAuthenticationFilter::class.java).
|
||||||
|
sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
67
src/main/kotlin/com/aitrainer/api/security/JwtTokenUtil.kt
Normal file
67
src/main/kotlin/com/aitrainer/api/security/JwtTokenUtil.kt
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
package com.aitrainer.api.security
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
import java.util.*
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
|
import io.jsonwebtoken.Claims
|
||||||
|
import io.jsonwebtoken.Jwts
|
||||||
|
import io.jsonwebtoken.SignatureAlgorithm
|
||||||
|
|
||||||
|
|
||||||
|
@Component
|
||||||
|
class JwtTokenUtil : Serializable {
|
||||||
|
@Value("\${jwt.secret}")
|
||||||
|
private val secret: String? = null
|
||||||
|
fun getUsernameFromToken(token: String?): String {
|
||||||
|
return getClaimFromToken(token, Claims::getSubject)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getIssuedAtDateFromToken(token: String?): Date {
|
||||||
|
return getClaimFromToken<Date>(token, Claims::getIssuedAt)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getExpirationDateFromToken(token: String?): Date {
|
||||||
|
return getClaimFromToken<Date>(token, Claims::getExpiration)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> getClaimFromToken( token: String?, claimsResolver: ( Claims.()-> T ) ): T {
|
||||||
|
val claims: Claims = getAllClaimsFromToken(token)
|
||||||
|
return claims.claimsResolver()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getAllClaimsFromToken(token: String?): Claims {
|
||||||
|
return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).body
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isTokenExpired(token: String): Boolean {
|
||||||
|
val expiration: Date = getExpirationDateFromToken(token)
|
||||||
|
return expiration.before(Date())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun generateToken(userDetails: UserDetails): String {
|
||||||
|
val claims: Map<String, Any> = HashMap()
|
||||||
|
return doGenerateToken(claims, userDetails.username)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun doGenerateToken(claims: Map<String, Any>, subject: String): String {
|
||||||
|
return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(Date(System.currentTimeMillis()))
|
||||||
|
.setExpiration(Date(System.currentTimeMillis() + JWT_TOKEN_VALIDITY * 1000)).signWith(SignatureAlgorithm.HS512, secret).compact()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun canTokenBeRefreshed(token: String): Boolean {
|
||||||
|
return !isTokenExpired(token)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun validateToken(token: String, userDetails: UserDetails): Boolean {
|
||||||
|
val username = getUsernameFromToken(token)
|
||||||
|
return username == userDetails.username && !isTokenExpired(token)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val serialVersionUID = -2550185165626007488L
|
||||||
|
const val JWT_TOKEN_VALIDITY = 5 * 60 * 60.toLong()
|
||||||
|
}
|
||||||
|
}
|
10
src/main/kotlin/com/aitrainer/api/service/CustomerService.kt
Normal file
10
src/main/kotlin/com/aitrainer/api/service/CustomerService.kt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package com.aitrainer.api.service
|
||||||
|
|
||||||
|
import com.aitrainer.api.model.Customer
|
||||||
|
import org.springframework.data.jpa.repository.Query
|
||||||
|
import org.springframework.data.repository.query.Param
|
||||||
|
|
||||||
|
interface CustomerService {
|
||||||
|
@Query("FROM customer WHERE active = :active ")
|
||||||
|
fun findByActive(@Param("active") active: String? ): List<Customer>
|
||||||
|
}
|
10
src/main/kotlin/com/aitrainer/api/service/ExerciseService.kt
Normal file
10
src/main/kotlin/com/aitrainer/api/service/ExerciseService.kt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package com.aitrainer.api.service
|
||||||
|
|
||||||
|
import com.aitrainer.api.model.Exercises
|
||||||
|
import org.springframework.data.jpa.repository.Query
|
||||||
|
import org.springframework.data.repository.query.Param
|
||||||
|
|
||||||
|
interface ExerciseService {
|
||||||
|
@Query("FROM exercises WHERE customer_id = :customerId")
|
||||||
|
fun findAllByCustomerId( @Param("customerId") customerId: Long? ): List<Exercises>
|
||||||
|
}
|
19
src/main/kotlin/com/aitrainer/api/service/ServiceBeans.kt
Normal file
19
src/main/kotlin/com/aitrainer/api/service/ServiceBeans.kt
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package com.aitrainer.api.service
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean
|
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
|
||||||
|
/*
|
||||||
|
Commonly used Beans
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Component
|
||||||
|
class ServiceBeans {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
fun passwordEncoder(): PasswordEncoder {
|
||||||
|
return BCryptPasswordEncoder()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package com.aitrainer.api.service
|
||||||
|
|
||||||
|
import com.aitrainer.api.model.Customer
|
||||||
|
import com.aitrainer.api.repository.CustomerRepository
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.security.core.GrantedAuthority
|
||||||
|
import org.springframework.security.core.userdetails.User
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails
|
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService
|
||||||
|
import org.springframework.security.core.authority.SimpleGrantedAuthority
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
import org.springframework.transaction.annotation.Transactional
|
||||||
|
import kotlin.collections.HashSet
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class UserDetailsServiceImpl: UserDetailsService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private lateinit var customerRepository: CustomerRepository
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
override fun loadUserByUsername(username: String?): UserDetails {
|
||||||
|
val customer: Customer? = customerRepository.findByEmail(username)
|
||||||
|
|
||||||
|
val grantedAuthorities = HashSet<GrantedAuthority>()
|
||||||
|
grantedAuthorities.add(SimpleGrantedAuthority("user"))
|
||||||
|
|
||||||
|
if (customer != null) {
|
||||||
|
return User(customer.email, customer.password, grantedAuthorities)
|
||||||
|
} else {throw Exception("User does not exist")}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
13
src/main/resources/application-dev.properties
Normal file
13
src/main/resources/application-dev.properties
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
spring.profiles.active=dev
|
||||||
|
## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
|
||||||
|
#spring.datasource.url = jdbc:mysql://localhost:3306/aitrainer?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false
|
||||||
|
spring.datasource.url = jdbc:mysql://localhost:3306/aitrainer?serverTimezone=CET&useSSL=false&characterEncoding=UTF-8&allowMultiQueries=true
|
||||||
|
spring.datasource.username = aitrainer
|
||||||
|
spring.datasource.password = andio2009
|
||||||
|
|
||||||
|
|
||||||
|
## Hibernate Properties
|
||||||
|
|
||||||
|
|
||||||
|
# The SQL dialect makes Hibernate generate better SQL for the chosen database
|
||||||
|
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
|
13
src/main/resources/application-prod.properties
Normal file
13
src/main/resources/application-prod.properties
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
spring.profiles.active=prod
|
||||||
|
## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
|
||||||
|
#spring.datasource.url = jdbc:mysql://localhost:3306/aitrainer?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false
|
||||||
|
spring.datasource.url = jdbc:mysql://localhost:3306/aitrainer?serverTimezone=CET&useSSL=false&characterEncoding=UTF-8&allowPublicKeyRetrieval=true&allowMultiQueries=true
|
||||||
|
spring.datasource.username = aitrainer
|
||||||
|
spring.datasource.password = andio2009
|
||||||
|
|
||||||
|
|
||||||
|
## Hibernate Properties
|
||||||
|
|
||||||
|
|
||||||
|
# The SQL dialect makes Hibernate generate better SQL for the chosen database
|
||||||
|
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
|
13
src/main/resources/application-test.properties
Normal file
13
src/main/resources/application-test.properties
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
spring.profiles.active=test
|
||||||
|
## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
|
||||||
|
#spring.datasource.url = jdbc:mysql://localhost:3306/aitrainer?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false
|
||||||
|
spring.datasource.url = jdbc:mysql://mysql:3306/aitrainer?serverTimezone=CET&useSSL=false&characterEncoding=UTF-8&allowPublicKeyRetrieval=true&allowMultiQueries=true
|
||||||
|
spring.datasource.username = root
|
||||||
|
spring.datasource.password = andio2009
|
||||||
|
|
||||||
|
|
||||||
|
## Hibernate Properties
|
||||||
|
|
||||||
|
|
||||||
|
# The SQL dialect makes Hibernate generate better SQL for the chosen database
|
||||||
|
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
|
21
src/main/resources/application.properties
Normal file
21
src/main/resources/application.properties
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
spring.profiles.active=dev,test,prod
|
||||||
|
## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
|
||||||
|
#spring.datasource.url = jdbc:mysql://localhost:3306/aitrainer?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false
|
||||||
|
spring.datasource.url = jdbc:mysql://localhost:3306/aitrainer?serverTimezone=CET&useSSL=false&characterEncoding=UTF-8&allowMultiQueries=true
|
||||||
|
spring.datasource.username = aitrainer
|
||||||
|
spring.datasource.password = andio2009
|
||||||
|
|
||||||
|
|
||||||
|
## Hibernate Properties
|
||||||
|
|
||||||
|
|
||||||
|
# The SQL dialect makes Hibernate generate better SQL for the chosen database
|
||||||
|
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
|
||||||
|
|
||||||
|
logging.config=classpath:logback-spring.xml
|
||||||
|
logging.file=logs
|
||||||
|
|
||||||
|
# if the database structure has been changed, increment this version number
|
||||||
|
application.version=0.0.3
|
||||||
|
|
||||||
|
jwt.secret=aitrainer
|
41
src/main/resources/logback-spring.xml
Normal file
41
src/main/resources/logback-spring.xml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<property resource="application.properties"/>
|
||||||
|
|
||||||
|
<appender name="FILE"
|
||||||
|
class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<file>${logging.file}/aitrainer.log</file>
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
|
<fileNamePattern>${logging.file}/aitrainer.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
|
||||||
|
<timeBasedFileNamingAndTriggeringPolicy
|
||||||
|
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||||
|
<maxFileSize>50MB</maxFileSize>
|
||||||
|
</timeBasedFileNamingAndTriggeringPolicy>
|
||||||
|
<maxHistory>30</maxHistory>
|
||||||
|
</rollingPolicy>
|
||||||
|
|
||||||
|
<encoder>
|
||||||
|
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%level] [%thread] [%logger:%line] %msg%n
|
||||||
|
</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%level] [%thread] [%logger:%line] %msg%n
|
||||||
|
</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- <logger name="org.springframework" level="DEBUG" /> -->
|
||||||
|
<logger name="com.aitrainer" level="INFO" />
|
||||||
|
<logger name="org.hibernate" level="INFO" />
|
||||||
|
|
||||||
|
|
||||||
|
<root level="INFO">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
<appender-ref ref="FILE" />
|
||||||
|
</root>
|
||||||
|
|
||||||
|
</configuration>
|
@ -0,0 +1,34 @@
|
|||||||
|
package com.aitrainer.api.test
|
||||||
|
|
||||||
|
import com.aitrainer.api.controller.ApplicationProperties
|
||||||
|
import com.aitrainer.api.controller.Singleton
|
||||||
|
import com.aitrainer.api.repository.ConfigurationRepository
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest
|
||||||
|
import java.sql.ResultSet
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class ApplicationStartTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private lateinit var configurationRepository: ConfigurationRepository
|
||||||
|
@Autowired
|
||||||
|
private lateinit var properties: ApplicationProperties
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testDBCheck() {
|
||||||
|
Singleton.checkDBUpdate(this.configurationRepository, this.properties)
|
||||||
|
|
||||||
|
var foundTable = false
|
||||||
|
val rs: ResultSet = Singleton.execQuery("Show tables;")
|
||||||
|
while ( rs.next() ) {
|
||||||
|
if ( rs.getString("tables_in_aitrainer") == "customer_information" ) {
|
||||||
|
foundTable = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(foundTable, true)
|
||||||
|
}
|
||||||
|
}
|
25
src/test/kotlin/com/aitrainer/api/test/AuthenticationTest.kt
Normal file
25
src/test/kotlin/com/aitrainer/api/test/AuthenticationTest.kt
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package com.aitrainer.api.test
|
||||||
|
|
||||||
|
import com.aitrainer.api.security.JwtAuthenticationController
|
||||||
|
import com.aitrainer.api.security.JwtRequest
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest
|
||||||
|
import org.springframework.http.HttpStatus
|
||||||
|
import org.springframework.http.ResponseEntity
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class AuthenticationTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private lateinit var authController: JwtAuthenticationController
|
||||||
|
@Test
|
||||||
|
fun testAuthentication() {
|
||||||
|
val response: ResponseEntity<*>
|
||||||
|
val jwtRequest = JwtRequest("bosi", "andio2009")
|
||||||
|
response = authController.generateAuthenticationToken(jwtRequest)
|
||||||
|
assertEquals(response.statusCode, HttpStatus.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
31
src/test/kotlin/com/aitrainer/api/test/ConfigurationTest.kt
Normal file
31
src/test/kotlin/com/aitrainer/api/test/ConfigurationTest.kt
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package com.aitrainer.api.test
|
||||||
|
|
||||||
|
import com.aitrainer.api.controller.ConfigurationController
|
||||||
|
import com.aitrainer.api.model.Configuration
|
||||||
|
import com.aitrainer.api.repository.ConfigurationRepository
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class ConfigurationTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private lateinit var configurationRepository: ConfigurationRepository
|
||||||
|
private lateinit var configurationController: ConfigurationController
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testUpdateConfig() {
|
||||||
|
val config: Configuration = configurationRepository.findByConfigKey("db_version")
|
||||||
|
config.configValue = "0.0.2"
|
||||||
|
|
||||||
|
configurationController = ConfigurationController(configurationRepository)
|
||||||
|
val updatedConfig: Configuration = configurationController.updateConfiguration(config)
|
||||||
|
assertEquals(updatedConfig.configValue, "0.0.2")
|
||||||
|
|
||||||
|
val foundConfig: Configuration = configurationRepository.findByConfigKey("db_version")
|
||||||
|
assertEquals(foundConfig.configValue, "0.0.2")
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.aitrainer.api.test
|
||||||
|
|
||||||
|
import com.aitrainer.api.model.CustomerInformation
|
||||||
|
import com.aitrainer.api.repository.CustomerInformationRepository
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class CustomerInformationTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private lateinit var customerInformationRepository: CustomerInformationRepository
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getActiveCustomerInformation() {
|
||||||
|
val dateTime = "2020-06-01 09:00:00"
|
||||||
|
val info: List<CustomerInformation> = this.customerInformationRepository.
|
||||||
|
findByDisplayBeginLessThanAndDisplayEndGreaterThan(dateTime, dateTime )
|
||||||
|
assertEquals(info.size, 2)
|
||||||
|
assertEquals(info.first().title, "Fekvőtámasz világcsúcs")
|
||||||
|
}
|
||||||
|
}
|
122
src/test/kotlin/com/aitrainer/api/test/CustomerTests.kt
Normal file
122
src/test/kotlin/com/aitrainer/api/test/CustomerTests.kt
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
package com.aitrainer.api.test
|
||||||
|
|
||||||
|
import com.aitrainer.api.controller.CustomerController
|
||||||
|
import com.aitrainer.api.model.Customer
|
||||||
|
import com.aitrainer.api.model.User
|
||||||
|
import com.aitrainer.api.repository.CustomerRepository
|
||||||
|
import com.aitrainer.api.service.ServiceBeans
|
||||||
|
import org.junit.jupiter.api.BeforeAll
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.TestInstance
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest
|
||||||
|
import org.springframework.http.HttpStatus
|
||||||
|
import org.springframework.http.ResponseEntity
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertNotNull
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
|
class CustomerTests {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private var serviceBean: ServiceBeans? = null
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
fun init() {
|
||||||
|
if ( serviceBean == null ) { serviceBean = ServiceBeans() }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private lateinit var customerRepository: CustomerRepository
|
||||||
|
private var insertedId: Long? = null
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testGet() {
|
||||||
|
val id: Long = 7
|
||||||
|
val customer: Customer = customerRepository.findById( id ).orElse(null)
|
||||||
|
assertEquals( customer.name, "Átlag 18 éves fiú")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testInsert() {
|
||||||
|
val newCustomer = Customer("Bossanyi", "Tibor", "", 48, "m")
|
||||||
|
val savedCustomer: Customer = customerRepository.save(newCustomer)
|
||||||
|
assertEquals(savedCustomer.age, 48)
|
||||||
|
|
||||||
|
this.insertedId = savedCustomer.customer_id
|
||||||
|
|
||||||
|
val customer: Customer = customerRepository.findById( savedCustomer.customer_id ).orElse(null)
|
||||||
|
assertEquals( customer.firstname, "Tibor")
|
||||||
|
|
||||||
|
this.testUpdate(savedCustomer.customer_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testUpdate( customerId: Long ) {
|
||||||
|
val id: Long? = customerId
|
||||||
|
assertNotNull(id)
|
||||||
|
|
||||||
|
val updatedCustomer: Customer = customerRepository.findById( id ).orElse(null)
|
||||||
|
|
||||||
|
assertNotNull(updatedCustomer)
|
||||||
|
updatedCustomer.firstname ="Tiborka"
|
||||||
|
|
||||||
|
val customer: Customer = customerRepository.save( updatedCustomer )
|
||||||
|
assertEquals( customer.firstname, "Tiborka")
|
||||||
|
|
||||||
|
customerRepository.delete(updatedCustomer)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testRegistration() {
|
||||||
|
val json = "{\"username\":\"bosi@example.com\",\"password\":\"94385\"}"
|
||||||
|
val user: User = User().fromJson(json)
|
||||||
|
assertEquals(user.username, "bosi@example.com")
|
||||||
|
val customer = Customer()
|
||||||
|
with(customer) {
|
||||||
|
email = user.username
|
||||||
|
password = user.password
|
||||||
|
}
|
||||||
|
val customerController = CustomerController(customerRepository)
|
||||||
|
customerController.serviceBeans = serviceBean
|
||||||
|
var response: ResponseEntity<*> = customerController.registration(json)
|
||||||
|
val newCustomer: Customer? = response.body as Customer
|
||||||
|
assertEquals(response.statusCode, HttpStatus.OK)
|
||||||
|
|
||||||
|
val json2 = "{\"username\":\"bosi@example.com\",\"password\":\"934345\"}"
|
||||||
|
response = customerController.registration(json2)
|
||||||
|
assertEquals(response.statusCode, HttpStatus.BAD_REQUEST)
|
||||||
|
|
||||||
|
if ( newCustomer != null) {
|
||||||
|
customerRepository.delete(newCustomer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun testLogin() {
|
||||||
|
val json = "{\"username\":\"bosi2@example.com\",\"password\":\"94333385\"}"
|
||||||
|
val user: User = User().fromJson(json)
|
||||||
|
val customer = Customer()
|
||||||
|
with(customer) {
|
||||||
|
email = user.username
|
||||||
|
password = user.password
|
||||||
|
}
|
||||||
|
val customerController = CustomerController(customerRepository)
|
||||||
|
customerController.serviceBeans = serviceBean
|
||||||
|
var response: ResponseEntity<*> = customerController.registration(json)
|
||||||
|
val newCustomer: Customer? = response.body as Customer
|
||||||
|
assertEquals(response.statusCode, HttpStatus.OK)
|
||||||
|
|
||||||
|
response = customerController.login(json)
|
||||||
|
val loginedCustomer: Customer? = response.body as Customer
|
||||||
|
assertEquals(response.statusCode, HttpStatus.OK)
|
||||||
|
if ( loginedCustomer != null ) {
|
||||||
|
assertEquals(loginedCustomer.email, ("bosi2@example.com") )
|
||||||
|
} else {
|
||||||
|
assert(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( newCustomer != null) {
|
||||||
|
customerRepository.delete(newCustomer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
44
src/test/kotlin/com/aitrainer/api/test/ExerciseTest.kt
Normal file
44
src/test/kotlin/com/aitrainer/api/test/ExerciseTest.kt
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package com.aitrainer.api.test
|
||||||
|
|
||||||
|
import com.aitrainer.api.model.Exercises
|
||||||
|
import com.aitrainer.api.repository.ExercisesRepository
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class ExerciseTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private lateinit var exerciseRepository: ExercisesRepository
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testGet() {
|
||||||
|
var id: Long = 1
|
||||||
|
|
||||||
|
val exercises: List<Exercises> = exerciseRepository.getAllByCustomerId( id )
|
||||||
|
assertEquals( exercises[0].quantity, 12)
|
||||||
|
|
||||||
|
id = 100000
|
||||||
|
val exercises2: List<Exercises> = exerciseRepository.getAllByCustomerId( id )
|
||||||
|
|
||||||
|
assertEquals( exercises2.size, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testInsert() {
|
||||||
|
val exercise = Exercises(
|
||||||
|
exerciseTypeId = 3,
|
||||||
|
customerId = 11,
|
||||||
|
quantity = 100,
|
||||||
|
dateAdd = "2020-05-13 04:32:00",
|
||||||
|
unit = "repeat",
|
||||||
|
restTime = null
|
||||||
|
)
|
||||||
|
val exerciseNew = exerciseRepository.save(exercise)
|
||||||
|
assertTrue(exerciseNew.exerciseId > 2)
|
||||||
|
exerciseRepository.delete(exercise)
|
||||||
|
}
|
||||||
|
}
|
49
src/test/kotlin/com/aitrainer/api/test/ExerciseTypeTest.kt
Normal file
49
src/test/kotlin/com/aitrainer/api/test/ExerciseTypeTest.kt
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package com.aitrainer.api.test
|
||||||
|
|
||||||
|
import com.aitrainer.api.model.ExerciseType
|
||||||
|
import com.aitrainer.api.repository.ExerciseTypeRepository
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class ExerciseTypeTest {
|
||||||
|
private val logger = LoggerFactory.getLogger(javaClass)
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private lateinit var exerciseTypeRepository: ExerciseTypeRepository
|
||||||
|
private var insertedId: Long = 0
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testGet() {
|
||||||
|
val id: Long = 7
|
||||||
|
val extype: ExerciseType = exerciseTypeRepository.findById(id).orElse(null)
|
||||||
|
assertEquals(extype.name, "4x10m-es ingafutás")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testGetAll() {
|
||||||
|
val exerciseTypes: List<ExerciseType> = exerciseTypeRepository.findAll()
|
||||||
|
assertEquals(exerciseTypes[0].exerciseTypeId, 1)
|
||||||
|
assertEquals(exerciseTypes[0].name, "Melső fekvőtámasz 1 perc")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testInsert(){
|
||||||
|
logger.info("Add 'Húzodzkodás 2")
|
||||||
|
val newEx = ExerciseType( "Húzodzkodás 2", " A legtöbb húzodszkodást 24 óra alatt John Ort érte el 7600-al 2016-ban. ", null )
|
||||||
|
val savedEx: ExerciseType = exerciseTypeRepository.save(newEx)
|
||||||
|
assertEquals(savedEx.name, "Húzodzkodás 2")
|
||||||
|
|
||||||
|
this.insertedId = savedEx.exerciseTypeId
|
||||||
|
|
||||||
|
logger.info("Find 'Húzodzkodás 2")
|
||||||
|
val extype: ExerciseType = exerciseTypeRepository.findById( savedEx.exerciseTypeId ).orElse(null)
|
||||||
|
assertEquals( extype.name, "Húzodzkodás 2")
|
||||||
|
|
||||||
|
logger.info("Delete 'Húzodzkodás 2")
|
||||||
|
exerciseTypeRepository.delete(extype)
|
||||||
|
}
|
||||||
|
}
|
27
src/test/kotlin/com/aitrainer/api/test/PropertiesTest.kt
Normal file
27
src/test/kotlin/com/aitrainer/api/test/PropertiesTest.kt
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package com.aitrainer.api.test
|
||||||
|
|
||||||
|
import com.aitrainer.api.controller.ApplicationProperties
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class PropertiesTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private lateinit var properties: ApplicationProperties
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testProperties() {
|
||||||
|
val version: String = properties.getVersion()
|
||||||
|
assertEquals(version, "0.0.2")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testDatasourceUrl() {
|
||||||
|
val url: String = properties.getDatasourceUrl()
|
||||||
|
assertEquals(url, "jdbc:mysql://localhost:3306/aitrainer?serverTimezone=CET&useSSL=false&characterEncoding=UTF-8&allowMultiQueries=true")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user