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