From 8e7e8ab4e1fcf44d47206924a0576d759f0d7ef4 Mon Sep 17 00:00:00 2001 From: "Tibor Bossanyi (Freelancer)" Date: Sun, 2 Oct 2022 15:13:36 +0200 Subject: [PATCH] API 1.0.56 SSL domain extension to workouttest.org --- build.gradle.kts | 4 +- data/db/update_1_0_56.sql | 5 + gradle/wrapper/gradle-wrapper.properties | 4 +- .../com/aitrainer/api/ApiApplication.kt | 2 +- .../security/JwtAuthenticationController.kt | 6 +- .../com/aitrainer/api/security/JwtRequest.kt | 11 +- src/main/resources/application-dev.properties | 5 +- .../resources/application-prod.properties | 13 +- .../resources/application-test.properties | 2 +- .../resources/application-testmac.properties | 2 +- src/main/resources/application.properties | 5 +- src/main/resources/application.ssl.properties | 10 +- .../keystore/workouttest/openssl.cnf | 352 ++++++++++++++++++ .../keystore/workouttest/workouttest_org.crt | Bin 0 -> 1059 bytes .../keystore/workouttest/workouttest_org.jks | Bin 0 -> 2930 bytes .../keystore/workouttest/workouttest_org.key | 28 ++ .../keystore/workouttest/workouttest_org.p12 | Bin 0 -> 2740 bytes .../keystore/workouttest/workouttest_org.pem | 25 ++ src/main/resources/logback-spring.xml | 3 +- .../com/aitrainer/api/test/AppPackageTest.kt | 2 +- 20 files changed, 438 insertions(+), 41 deletions(-) create mode 100644 data/db/update_1_0_56.sql create mode 100644 src/main/resources/keystore/workouttest/openssl.cnf create mode 100644 src/main/resources/keystore/workouttest/workouttest_org.crt create mode 100644 src/main/resources/keystore/workouttest/workouttest_org.jks create mode 100644 src/main/resources/keystore/workouttest/workouttest_org.key create mode 100644 src/main/resources/keystore/workouttest/workouttest_org.p12 create mode 100644 src/main/resources/keystore/workouttest/workouttest_org.pem diff --git a/build.gradle.kts b/build.gradle.kts index cd9a9cd..4bac556 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -11,7 +11,7 @@ plugins { } group = "com.aitrainer" -version = "1.0.55" +version = "1.0.56" java.sourceCompatibility = JavaVersion.VERSION_1_8 repositories { @@ -54,7 +54,7 @@ tasks.withType { tasks.withType { kotlinOptions { - freeCompilerArgs = listOf("-Xjsr305=strict") + freeCompilerArgs = listOf("-Xjsr305=strict", "-opt-in=kotlin.RequiresOptIn") jvmTarget = "1.8" } } diff --git a/data/db/update_1_0_56.sql b/data/db/update_1_0_56.sql new file mode 100644 index 0000000..d08204c --- /dev/null +++ b/data/db/update_1_0_56.sql @@ -0,0 +1,5 @@ +START TRANSACTION; + +UPDATE configuration set config_value = "1.0.56", date_change=CURRENT_DATE WHERE config_key = "db_version"; + +COMMIT; diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 9543e93..00e33ed 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists \ No newline at end of file +zipStorePath=wrapper/dists diff --git a/src/main/kotlin/com/aitrainer/api/ApiApplication.kt b/src/main/kotlin/com/aitrainer/api/ApiApplication.kt index 0b188ad..f5ed0ac 100644 --- a/src/main/kotlin/com/aitrainer/api/ApiApplication.kt +++ b/src/main/kotlin/com/aitrainer/api/ApiApplication.kt @@ -16,7 +16,7 @@ class ApiApplication { fun stringEncryptor(): StringEncryptor? { val encryptor = PooledPBEStringEncryptor() val config = SimpleStringPBEConfig() - config.password = "Tibor" + config.password = "workouttest" config.algorithm = "PBEWithMD5AndDES" config.setKeyObtentionIterations("1000") config.setPoolSize("1") diff --git a/src/main/kotlin/com/aitrainer/api/security/JwtAuthenticationController.kt b/src/main/kotlin/com/aitrainer/api/security/JwtAuthenticationController.kt index 4468cd0..717cdc1 100644 --- a/src/main/kotlin/com/aitrainer/api/security/JwtAuthenticationController.kt +++ b/src/main/kotlin/com/aitrainer/api/security/JwtAuthenticationController.kt @@ -9,7 +9,7 @@ import org.springframework.security.authentication.DisabledException import org.springframework.security.authentication.UsernamePasswordAuthenticationToken import org.springframework.web.bind.annotation.* import org.springframework.stereotype.Component - +import javax.servlet.http.HttpServletRequest @Component @@ -27,9 +27,10 @@ class JwtAuthenticationController { private val jwtUserDetailsService: UserDetailsServiceImpl? = null @PostMapping("/authenticate") - fun generateAuthenticationToken(@RequestBody authenticationRequest: JwtRequest): ResponseEntity<*> { + fun generateAuthenticationToken(@RequestBody authenticationRequest: JwtRequest, request: HttpServletRequest): ResponseEntity<*> { authenticate(authenticationRequest.username!!, authenticationRequest.password!!) + println("authenticating from: ${request.remoteAddr}") val userDetails = jwtUserDetailsService ?.loadUserByUsername(authenticationRequest.username) @@ -40,7 +41,6 @@ class JwtAuthenticationController { private fun authenticate(username: String, password: String) { try { authenticationManager!!.authenticate(UsernamePasswordAuthenticationToken(username, password)) - println("authenticating....") } catch (e: DisabledException) { throw Exception("USER_DISABLED", e) } catch (e: BadCredentialsException) { diff --git a/src/main/kotlin/com/aitrainer/api/security/JwtRequest.kt b/src/main/kotlin/com/aitrainer/api/security/JwtRequest.kt index 58cbb19..98f9504 100644 --- a/src/main/kotlin/com/aitrainer/api/security/JwtRequest.kt +++ b/src/main/kotlin/com/aitrainer/api/security/JwtRequest.kt @@ -3,15 +3,8 @@ 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 - } +class JwtRequest//default constructor for JSON Parsing + (var username: String?, var password: String?) : Serializable { companion object { private const val serialVersionUID = 5926468583005150707L diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index 292283c..e89e85a 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -1,10 +1,9 @@ spring.config.activate.on-profile=dev spring.config.use-legacy-processing = true -## 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/aitrainer2?serverTimezone=CET&useSSL=false&characterEncoding=UTF-8&allowMultiQueries=true spring.datasource.username = aitrainer -spring.datasource.password = andio2009 +spring.datasource.password = ENC(WZplPYr8WmrLHshesY4T6oXplK3MlUVJ) ## Hibernate Properties diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties index f9fd54d..b2064db 100644 --- a/src/main/resources/application-prod.properties +++ b/src/main/resources/application-prod.properties @@ -1,13 +1,8 @@ spring.config.activate.on-profile=prod spring.config.use-legacy-processing = true -## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties) -spring.datasource.url = jdbc:mysql://62.171.188.119:33060/aitrainer?serverTimezone=CET&useSSL=false&characterEncoding=UTF-8&allowPublicKeyRetrieval=true&allowMultiQueries=true + spring.datasource.username = aitrainer -spring.datasource.password = andio2009 - - -## Hibernate Properties - +spring.datasource.password = ENC(WZplPYr8WmrLHshesY4T6oXplK3MlUVJ) # The SQL dialect makes Hibernate generate better SQL for the chosen database spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect @@ -16,7 +11,7 @@ spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDial logging.config=classpath:logback-spring.xml logging.file=logs -# if the database structure has been changed, increment this version number -application.version=1.0.55 +# if the database structue has been changed, increment this version number +application.version=1.0.56 jwt.secret=aitrainer \ No newline at end of file diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties index 65acf1b..317ea38 100644 --- a/src/main/resources/application-test.properties +++ b/src/main/resources/application-test.properties @@ -4,7 +4,7 @@ spring.config.use-legacy-processing = true #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 +spring.datasource.password = ENC(WZplPYr8WmrLHshesY4T6oXplK3MlUVJ) ## Hibernate Properties diff --git a/src/main/resources/application-testmac.properties b/src/main/resources/application-testmac.properties index 5d1612c..435c8f6 100644 --- a/src/main/resources/application-testmac.properties +++ b/src/main/resources/application-testmac.properties @@ -4,7 +4,7 @@ spring.config.use-legacy-processing = true #spring.datasource.url = jdbc:mysql://localhost:3306/aitrainer?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false spring.datasource.url = jdbc:mysql://127.0.0.1:3306/aitrainer2?serverTimezone=CET&useSSL=false&characterEncoding=UTF-8&allowPublicKeyRetrieval=true&allowMultiQueries=true spring.datasource.username = root -spring.datasource.password = andio2009 +spring.datasource.password = ENC(WZplPYr8WmrLHshesY4T6oXplK3MlUVJ) ## Hibernate Properties diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 37f1ce2..b634519 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -4,7 +4,7 @@ spring.config.use-legacy-processing = true #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/aitrainer2?serverTimezone=CET&useSSL=false&characterEncoding=UTF-8&allowMultiQueries=true spring.datasource.username = aitrainer -spring.datasource.password = andio2009 +spring.datasource.password = ENC(WZplPYr8WmrLHshesY4T6oXplK3MlUVJ) ## Hibernate Properties @@ -17,7 +17,6 @@ logging.config=classpath:logback-spring.xml logging.file=logs # if the database structure has been changed, increment this version number -application.version=1.0.55 +application.version=1.0.56 jwt.secret=aitrainer -jasypt.encryptor.password=Tibor diff --git a/src/main/resources/application.ssl.properties b/src/main/resources/application.ssl.properties index a0d7cd4..c80ee01 100644 --- a/src/main/resources/application.ssl.properties +++ b/src/main/resources/application.ssl.properties @@ -6,14 +6,14 @@ jasypt.encryptor.bean=jasyptStringEncryptor # The format used for the keystore. It could be set to JKS in case it is a JKS file server.ssl.key-store-type=PKCS12 # The path to the keystore containing the certificate -server.ssl.key-store=classpath:keystore/aitrainer_server.p12 +server.ssl.key-store=classpath:keystore/workouttest/workouttest_org.p12 # The password used to generate the certificate -server.ssl.key-store-password=ENC(aI6iP8wGJ9dwIA+hKabwK/VDXe4NOrhl) +server.ssl.key-store-password=ENC(RscFQkhL3C0g88JIy9Ltju8jzg1+0PiS) # The alias mapped to the certificate -server.ssl.key-alias=aitrainer_server +server.ssl.key-alias=workouttest #trust store location -trust.store=classpath:keystore/aitrainer_server.p12 +trust.store=classpath:keystore/workouttest/workouttest_org.p12 #trust store password -trust.store.password=ENC(aI6iP8wGJ9dwIA+hKabwK/VDXe4NOrhl) +trust.store.password=ENC(RscFQkhL3C0g88JIy9Ltju8jzg1+0PiS) diff --git a/src/main/resources/keystore/workouttest/openssl.cnf b/src/main/resources/keystore/workouttest/openssl.cnf new file mode 100644 index 0000000..3e49b47 --- /dev/null +++ b/src/main/resources/keystore/workouttest/openssl.cnf @@ -0,0 +1,352 @@ +# +# OpenSSL example configuration file. +# This is mostly being used for generation of certificate requests. +# + +# Note that you can include other files from the main configuration +# file using the .include directive. +#.include filename + +# This definition stops the following lines choking if HOME isn't +# defined. +HOME = . + +# Extra OBJECT IDENTIFIER info: +#oid_file = $ENV::HOME/.oid +oid_section = new_oids + +# To use this configuration file with the "-extfile" option of the +# "openssl x509" utility, name here the section containing the +# X.509v3 extensions to use: +# extensions = +# (Alternatively, use a configuration file that has only +# X.509v3 extensions in its main [= default] section.) + +[ new_oids ] + +# We can add new OIDs in here for use by 'ca', 'req' and 'ts'. +# Add a simple OID like this: +# testoid1=1.2.3.4 +# Or use config file substitution like this: +# testoid2=${testoid1}.5.6 + +# Policies used by the TSA examples. +tsa_policy1 = 1.2.3.4.1 +tsa_policy2 = 1.2.3.4.5.6 +tsa_policy3 = 1.2.3.4.5.7 + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = ./demoCA # Where everything is kept +certs = $dir/certs # Where the issued certs are kept +crl_dir = $dir/crl # Where the issued crl are kept +database = $dir/index.txt # database index file. +#unique_subject = no # Set to 'no' to allow creation of + # several certs with same subject. +new_certs_dir = $dir/newcerts # default place for new certs. + +certificate = $dir/cacert.pem # The CA certificate +serial = $dir/serial # The current serial number +crlnumber = $dir/crlnumber # the current crl number + # must be commented out to leave a V1 CRL +crl = $dir/crl.pem # The current CRL +private_key = $dir/private/cakey.pem# The private key + +x509_extensions = usr_cert # The extensions to add to the cert + +# Comment out the following two lines for the "traditional" +# (and highly broken) format. +name_opt = ca_default # Subject Name options +cert_opt = ca_default # Certificate field options + +# Extension copying option: use with caution. +# copy_extensions = copy + +# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs +# so this is commented out by default to leave a V1 CRL. +# crlnumber must also be commented out to leave a V1 CRL. +# crl_extensions = crl_ext + +default_days = 365 # how long to certify for +default_crl_days= 30 # how long before next CRL +default_md = default # use public key default MD +preserve = no # keep passed DN ordering + +# A few difference way of specifying how similar the request should look +# For type CA, the listed attributes must be the same, and the optional +# and supplied fields are just that :-) +policy = policy_match + +# For the CA policy +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +# For the 'anything' policy +# At this point in time, you must list all acceptable 'object' +# types. +[ policy_anything ] +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +#################################################################### +[ req ] +default_bits = 2048 +default_keyfile = privkey.pem +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca # The extensions to add to the self signed cert + +# Passwords for private keys if not present they will be prompted for +# input_password = secret +# output_password = secret + +# This sets a mask for permitted string types. There are several options. +# default: PrintableString, T61String, BMPString. +# pkix : PrintableString, BMPString (PKIX recommendation before 2004) +# utf8only: only UTF8Strings (PKIX recommendation after 2004). +# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). +# MASK:XXXX a literal mask value. +# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings. +string_mask = utf8only + +# req_extensions = v3_req # The extensions to add to a certificate request + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = AU +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = Some-State + +localityName = Locality Name (eg, city) + +0.organizationName = Organization Name (eg, company) +0.organizationName_default = Internet Widgits Pty Ltd + +# we can do this but it is not needed normally :-) +#1.organizationName = Second Organization Name (eg, company) +#1.organizationName_default = World Wide Web Pty Ltd + +organizationalUnitName = Organizational Unit Name (eg, section) +#organizationalUnitName_default = + +commonName = Common Name (e.g. server FQDN or YOUR name) +commonName_max = 64 + +emailAddress = Email Address +emailAddress_max = 64 + +# SET-ex3 = SET extension number 3 + +[ req_attributes ] +challengePassword = A challenge password +challengePassword_min = 4 +challengePassword_max = 20 + +unstructuredName = An optional company name + +[ usr_cert ] + +# These extensions are added when 'ca' signs a request. + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE + +# Here are some examples of the usage of nsCertType. If it is omitted +# the certificate can be used for anything *except* object signing. + +# This is OK for an SSL server. +# nsCertType = server + +# For an object signing certificate this would be used. +# nsCertType = objsign + +# For normal client use this is typical +# nsCertType = client, email + +# and for everything including object signing: +# nsCertType = client, email, objsign + +# This is typical in keyUsage for a client certificate. +# keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment = "OpenSSL Generated Certificate" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +# This stuff is for subjectAltName and issuerAltname. +# Import the email address. +# subjectAltName=email:copy +# An alternative to produce certificates that aren't +# deprecated according to PKIX. +# subjectAltName=email:move + +# Copy subject details +# issuerAltName=issuer:copy + +#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem +#nsBaseUrl +#nsRevocationUrl +#nsRenewalUrl +#nsCaPolicyUrl +#nsSslServerName + +# This is required for TSA certificates. +# extendedKeyUsage = critical,timeStamping + +[ v3_req ] + +# Extensions to add to a certificate request + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v3_ca ] + + +# Extensions for a typical CA + + +# PKIX recommendation. + +subjectKeyIdentifier=hash + +authorityKeyIdentifier=keyid:always,issuer + +basicConstraints = critical,CA:true + +# Key usage: this is typical for a CA certificate. However since it will +# prevent it being used as an test self-signed certificate it is best +# left out by default. +# keyUsage = cRLSign, keyCertSign + +# Some might want this also +# nsCertType = sslCA, emailCA + +# Include email address in subject alt name: another PKIX recommendation +# subjectAltName=email:copy +# Copy issuer details +# issuerAltName=issuer:copy + +# DER hex encoding of an extension: beware experts only! +# obj=DER:02:03 +# Where 'obj' is a standard or added object +# You can even override a supported extension: +# basicConstraints= critical, DER:30:03:01:01:FF + +[ crl_ext ] + +# CRL extensions. +# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. + +# issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always + +[ proxy_cert_ext ] +# These extensions should be added when creating a proxy certificate + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE + +# Here are some examples of the usage of nsCertType. If it is omitted +# the certificate can be used for anything *except* object signing. + +# This is OK for an SSL server. +# nsCertType = server + +# For an object signing certificate this would be used. +# nsCertType = objsign + +# For normal client use this is typical +# nsCertType = client, email + +# and for everything including object signing: +# nsCertType = client, email, objsign + +# This is typical in keyUsage for a client certificate. +# keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment = "OpenSSL Generated Certificate" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +# This stuff is for subjectAltName and issuerAltname. +# Import the email address. +# subjectAltName=email:copy +# An alternative to produce certificates that aren't +# deprecated according to PKIX. +# subjectAltName=email:move + +# Copy subject details +# issuerAltName=issuer:copy + +#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem +#nsBaseUrl +#nsRevocationUrl +#nsRenewalUrl +#nsCaPolicyUrl +#nsSslServerName + +# This really needs to be in place for it to be a proxy certificate. +proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo + +#################################################################### +[ tsa ] + +default_tsa = tsa_config1 # the default TSA section + +[ tsa_config1 ] + +# These are used by the TSA reply generation only. +dir = ./demoCA # TSA root directory +serial = $dir/tsaserial # The current serial number (mandatory) +crypto_device = builtin # OpenSSL engine to use for signing +signer_cert = $dir/tsacert.pem # The TSA signing certificate + # (optional) +certs = $dir/cacert.pem # Certificate chain to include in reply + # (optional) +signer_key = $dir/private/tsakey.pem # The TSA private key (optional) +signer_digest = sha256 # Signing digest to use. (Optional) +default_policy = tsa_policy1 # Policy if request did not specify it + # (optional) +other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional) +digests = sha1, sha256, sha384, sha512 # Acceptable message digests (mandatory) +accuracy = secs:1, millisecs:500, microsecs:100 # (optional) +clock_precision_digits = 0 # number of digits after dot. (optional) +ordering = yes # Is ordering defined for timestamps? + # (optional, default: no) +tsa_name = yes # Must the TSA name be included in the reply? + # (optional, default: no) +ess_cert_id_chain = no # Must the ESS cert id chain be included? + # (optional, default: no) +ess_cert_id_alg = sha1 # algorithm to compute certificate + # identifier (optional, default: sha1) +[ subject_alt_name ] +subjectAltName = DNS:api-test.workouttest.org, DNS:api.workouttest.org, DNS:aitrainer.info, DNS:localhost diff --git a/src/main/resources/keystore/workouttest/workouttest_org.crt b/src/main/resources/keystore/workouttest/workouttest_org.crt new file mode 100644 index 0000000000000000000000000000000000000000..c30e05600acbe64713f4c770be1e1c1bc77fa586 GIT binary patch literal 1059 zcmXqLVv#p!VrE~!%*4pVB*JuC&U?wtu4CJ$`RY&cm$JFgcjdnUFB_*;n@8JsUPeZ4 zRtAH{IfmQ@oNUaYENsF|8Ks7T2K*on2M{=ii?Lmw=%sb zzqG(m$Up!j!p*~3oLW?tnVgxIZYW_O1`=cD;V;iG%FZt>DFGU%mzwJ z4sb?R2IeM4eg=akMlPl%Mn;A|&mE^&wqChh{?VId-ySRUWPc{aZikAOcu+V0Ga-pGD{)_$MQ`Jv?nI-)G$k$KFve_ca5ALk9 z@nkns&*y7yo;O$Mk!s>QF^ho80zp0&Ud4T051#~G*NEuTo1X4-{`xty%B=pnEzK!Y zSO2bA|I2)-lpOc9g3YUy4##jmV81fujPc8x$)ZZ-A)Ir@c$p>rIvw=JLb zFl^Vyp6&alKVvI>_3z$^Wpc48hZO5s5AE{hWnyMzU|bw-5NZ$%OewO0EItNaO%jO( znY!Slf}Cvfi_)8ffiimNf_#aYB}Ivud8tKunR#jXO`JLT$%#1``Nbv3K@Uvpz@TSj zIQede-79t0$+LMr`HVW{1mlP&%UU9Gcf-}EM{QNbq ztktfy+*aA!wZ?SX_D=zmbl=U|e84X7x#OhWUXd+&tM1L?4o!a2RbBJh(}Lsk6ajCk z_j81~vO=B+X>L7VxHxi6VT{0wwU>UV8pX)M?MYjK9D*JAP|{hG&@ OgrhWdJg-h--VOi>iHjis literal 0 HcmV?d00001 diff --git a/src/main/resources/keystore/workouttest/workouttest_org.jks b/src/main/resources/keystore/workouttest/workouttest_org.jks new file mode 100644 index 0000000000000000000000000000000000000000..d6c07a2115f56a07dd9b12578050ddef12f3551f GIT binary patch literal 2930 zcma);c{CIb*T>BmBkS0WjJ+&_nz5ICNw#TJgc-&bk~InyVeFG7vWz8UOHm||wUV8& zW+%&tM7BX0gU5T`=kz!f+x35O{_U|IuQ23BofJpUBTo{27?#-&?HA0AN0zLFYu&K)C+hU|>VoAk_XT zSrM`z9;qw?v(bsiroFBj{D8WH_>~j@cq82oD;tLofRi9x{Q)bG`BtQ_NjFjb~yP+RC3w z*MIz^Qi`dYL|z$>ODnzBb&5;c7GD;; zi&$OZupKg+>PuFjz^17RJW$hujH2H^2?h}k*UC)~$6<>-Hf&3?m|HWZIrowI=mdaY<3X+Zj3??brJZ#~ZzNm5s-XdEOx z-qrdHOAm)|saNl1C7dE(@E7-(n^=A58~(@sq}*#ZPd46BKwLYtb9dGw}7evz|0qv*%59Pd1W#qboX1-3kgn{KUm@Qa8W`b*u}j3 za=!=_!QZG@RIB~7$vLDRZo8k|LhP`{!jp!(!U+R6OSV*gd4lq1qU&-IA(SSOb|=0O z^(_yxee7M}V^q%fC?*2V`>@i#b{bR2|1m!Akx3>KV2|0>?Zq;cg*N zR1eLY*)paiUH4e+=`D(97j8vMMLv~x*S++I_rhPU^o0<{F%4kk{Q8#QRtceG;OerWv{$Q z79y?H99`q}=cBnfhj@FrHLEbcl;?eq6_~8FMF8Y$x@*vnC~%dEEEnJ2Z`m51suG+zXYm@LJnC zRVV4CFkMoen^dt_;^R@!#d?*fhW-K?3?RJDR}n!5JlnkW6p~!|ej1~lOd45j^=^;i z_Wo`4ivw4@YHyWXhRR)huIDQkmN>EW{XHhD&W3I`O(DI3SvvwPFO#=tR}gHtpq}B) zRarb!oxu)T&M7hV8a}A_$#bFemSqJGj-}4D{#&Hj+-%dJQ^?e!H7iu0n^0j`SrO=} zsZT2vmNZ6WN{uk@N-$NTc4Pf2gl6SrxYW8GcR1fINgRC%`FL*cArITSyP2{_hn2qd z%qcpPXQnT|7G70c4{Qp2AT$_O|5=kwUs>1e;!O{3hg}d4{TMpS8qw+l6?F|wJstLj zQ9c|c%-sEc?(i^JubT7TE>WsMyhwM@&u}gklrNJ*DVk(@T2-h~X?PF{J<1B&XNlm0Ksp~fKRS<-c#rPxiMi1E)7?dg{WHdk?e}@>sCwNvkk8 zkS%#?FXw*&Hh=3u1>G;0}gdZ_O0yoLG$A)^QroFV&y; zC=e+h@Lt$X?vHc@q`PnED9UxatF2Ip; zA0{{lhn0S3oN|kjj&nNX8)oj!4C-2DIB=ZchI1T9;ty|Cdieae>O`SzCuA~kNZ8YtJ%xu3umU+*9r1(JrelU*9 zuIj?VMKOstpM&r&ovy8c*5JhIkj<3KbYzwe@hI13+eXDS+VZ49Fmvn~F@A#-W7NA` z%Asr6@f*+x%l;U3u*HMtIA|uX3EMtvmMMWOjT|15GnGHHMH`&i)X4nU%7k^wj>7yt z*Bc;RwFLw;r_PsW57CEsE&)c48?-&MWr3Z*Md*8Ot*B#mxcd2;zM(ZaCWOtyPdfEM zi`5cE&1h{-oPbq#JF>*ZAqQ;!CrhXQmCW!H6QPAOP+;N{_d=~X<{IrI80;ZgsBBgb z4-FP3&8nMHq3d(};SfJ^%Yx_~U*F(Y!)#Zuuc9KIqCoVA53pFD9!uegl`IdeDoLmu z;MEmq+`lB&V@;fA^q;w=6B#thK?5xdEU57epy(~T+|~FLB&Necqke&{o0CZjHI@@e(FS za(I6|N$?b*UPB%o})w^7ktL%+geow4{~t88+5rEictxzm^Yt!;%(#C&bhRVl$Q z`?Cw~dPu2zFM;9@rI4-Ij&tE4J4-=Bk-&BKM|qfqf%e(~mmT+AG3$MMfu1T`sZk?_1OMek1fl+!Y8i>#Q3=$<~g)($Zf~5 z;!1|5#R64*#vrsn-pC{!!eiC#?$|0v&Gr5?;hQ7sMg^N!qpIRm^lD>lt!jBy)r#T8 ztrQDIK%CYr)(t61uKdLH^=GK|IRfM}QGUFBVSx85DaN}gwoDln3EnMgHs3q7+1Z;$ zL&x>%2`6a6q~(1_%$pJ;4hOf!>SgshubAq)s#cHtX17|3~YJvM}0d^>uG0GcH9ss1QNma_YVaE80bKvBJ#4BzU9S9E|PP( x+0QPR-C%8MepWQL9Q-4SsWd$d#FKVCAGI27sx_G+Q(QH$uMQ2bl>0wq{tJI7X}SOa literal 0 HcmV?d00001 diff --git a/src/main/resources/keystore/workouttest/workouttest_org.key b/src/main/resources/keystore/workouttest/workouttest_org.key new file mode 100644 index 0000000..74b37ed --- /dev/null +++ b/src/main/resources/keystore/workouttest/workouttest_org.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQD850GUOYXU03ft +R18Z71q6IEpirYdeSdJ4dlGbfNeLPDAnZqVP3JTuXv5R5LFTdRV3+qChPK9jcTFK +b+i/F5UnyfSaE+/E9fJjHWsUI+DcrjxJBzYnbw6Dg56dEuIlYe4WOFB5cBEOBA0h +vkrh5FLXKFiOLpdnTM/XzjZ5ao9+tINklav7fK/6N6UaHgvWcLOrIsNcC+AH1JTc +G0nPLYBuKCX+m9xt95aG1zA8hZ0Sk+MB2ZF2slgYh/ZRpsKvVDlnpadSWKGcsItL +1WIgyRphGtkHKFElCyYn/2wvcTFVnEBrtqea4Va68Yy3vpfmBnXq/t7Iph5dZMIh +fwXCuk0NAgMBAAECggEAca418T3mJaOk7di+K/dGjhHDvhWImt6OKC3vQvhcHy8/ +6gYe2wYpP/kdUox9FSm1K8hR+ghAQm/4GyCwu20LU+ZY+AVsKtnvSZRItLXn9uqv +GJiQRCuMl5tLagm589nQXtaTffLdB7LUgE18dYvfnO162PaiggGqD7SXEf7PX8E5 +6g4xpHivXM4XwIWSS/yhRUXo2r3XqE/b7UAR67ZCbOt8zBiawi9EQgcmDW896TVD +YHrW+/IZfpMM0r4gmglSrMONjbbi7zVvdwojwQEmdkfigWxAgAqUZMpDYgin6Yg2 +Zsvi7Erj6qBHTOPq5IOInI/xFDA2wBoBtnMY6uMldQKBgQD+4OL9IgViQFPU33Z4 +bk/QBs4BlPWDzh7kB18K9d0FFyI0bM0rtpzFoXx/evSzGvQBWICQw97dZ0Q/bLcn +pXeVB1tOtOHB7T4zW8x2y8g2Tm5oDP3ty1ihNceir9eJlKCRDkVeBPugprwUwDpL +g6x6sJNNEz6tW5BYtz+fP4muJwKBgQD+BCUDCGgkFEVl0qh0gAbXyh9dPKYdvh/G +14iXJEF5D8P/UiHG7ghD8xS8Io/Q5IFC6f2zew17QpeR5NUFEHeLbR+mMo48VD3O +bBjrX85YdrFnunPI7P4uBDWUDVWhTd+tdjlaITwvHjoOvxB6tzttE1zBegW/nVKi +4xNfnNnfqwKBgFivv8v8zorFf2YO65Y0LClidMQwJM3cJvuJZRTXQDTJO+mqAio3 +vI04B64EBqlbs5PUS8gTn7TCfgjjt0dgWB/PE4JrhjKIbqBITPj5J41d9STXgHQB +0bEmmXSOYx1ITiarJI/2g+f+nGtMB/zGsHlwf5DOJX0E41E7UjQDU9D5AoGBANf+ +UDaO/HbJYeVeRm2hu6/cJ+VRP/OEimK7PWM/qgi2FjRR83TDTPXyicwcG2xGEYAD +lf37AZCxJE8jZNuEkBJXvRTGYln8S/3tvxbOBZkFfH62deQBWXVpkOGOoSSjIjLO +l6ADKLjsG/QUFYAztG1gjHvcNW0k6nKlYgDoT/83AoGASoq88zgCGxiuFtrIhp2G +F+2bHRbQGAqZFjbPPnUNQQvhcOJlk9e/lPKDj+LVsktcgiYw7fkXt/5iIe/A8+eu +jbPLIVaMHVRbvEwfK54beP0C1mAoPVoV7FzcjLXYKQ9qCtYUGoyOuw0VkObvCZPN +LNHlhGznDS/xc0RB9TrMfgU= +-----END PRIVATE KEY----- diff --git a/src/main/resources/keystore/workouttest/workouttest_org.p12 b/src/main/resources/keystore/workouttest/workouttest_org.p12 new file mode 100644 index 0000000000000000000000000000000000000000..933e525977ded7695a805c75a8d74811ebe64e4b GIT binary patch literal 2740 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 hbk=kJMq95aB literal 0 HcmV?d00001 diff --git a/src/main/resources/keystore/workouttest/workouttest_org.pem b/src/main/resources/keystore/workouttest/workouttest_org.pem new file mode 100644 index 0000000..f8165a0 --- /dev/null +++ b/src/main/resources/keystore/workouttest/workouttest_org.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEHzCCAwegAwIBAgIUAtseS6TZisa3lk0vlE8aPNCO1P8wDQYJKoZIhvcNAQEL +BQAwgZwxCzAJBgNVBAYTAmh1MREwDwYDVQQIDAhidWRhcGVzdDERMA8GA1UEBwwI +YnVkYXBlc3QxEDAOBgNVBAoMB215Z3JvdXAxEjAQBgNVBAsMCXNlcnZpY2luZzEY +MBYGA1UEAwwPd29ya291dHRlc3QuY29tMScwJQYJKoZIhvcNAQkBFhh0aWJvci5i +b3NzYW55aUBnbWFpbC5jb20wHhcNMjIxMDAyMDgzNzU1WhcNMjMxMDAyMDgzNzU1 +WjCBnDELMAkGA1UEBhMCaHUxETAPBgNVBAgMCGJ1ZGFwZXN0MREwDwYDVQQHDAhi +dWRhcGVzdDEQMA4GA1UECgwHbXlncm91cDESMBAGA1UECwwJc2VydmljaW5nMRgw +FgYDVQQDDA93b3Jrb3V0dGVzdC5jb20xJzAlBgkqhkiG9w0BCQEWGHRpYm9yLmJv +c3NhbnlpQGdtYWlsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +APznQZQ5hdTTd+1HXxnvWrogSmKth15J0nh2UZt814s8MCdmpU/clO5e/lHksVN1 +FXf6oKE8r2NxMUpv6L8XlSfJ9JoT78T18mMdaxQj4NyuPEkHNidvDoODnp0S4iVh +7hY4UHlwEQ4EDSG+SuHkUtcoWI4ul2dMz9fONnlqj360g2SVq/t8r/o3pRoeC9Zw +s6siw1wL4AfUlNwbSc8tgG4oJf6b3G33lobXMDyFnRKT4wHZkXayWBiH9lGmwq9U +OWelp1JYoZywi0vVYiDJGmEa2QcoUSULJif/bC9xMVWcQGu2p5rhVrrxjLe+l+YG +der+3simHl1kwiF/BcK6TQ0CAwEAAaNXMFUwUwYDVR0RBEwwSoIYYXBpLXRlc3Qu +d29ya291dHRlc3Qub3JnghNhcGkud29ya291dHRlc3Qub3Jngg5haXRyYWluZXIu +aW5mb4IJbG9jYWxob3N0MA0GCSqGSIb3DQEBCwUAA4IBAQDJ7rg+6icFk5pz0DgF +WrPuuSpX9FNv/EjQQXCLG+6xEA1LdHFjs6jei9BDD0Rfn6zqOybWhNskvYqsNZa3 +8lCSLe6as8A+UedBkrtKWYQuqt6eC1Vj5Ip7fPNJOAjzlBBLGu+cEwpqVOQSKbXP +caNZrHFcEOin8Fb5xUNF86T8W1sbFE9bM4sljvGqNL4b8NyGcNjY+cfhyQx75uiv +64RSfWhiYVFePIJNg2VLipfkAcQvnI8CYVrLVZzkCgQsZHqFG5lAW/wxHBDw1Eww +s5msjnqK1hrVOMlUWx46zB0UQs5BadZ/urYEgXct/TjMAo04k9IvfOPSE1opLEnV +kgO3 +-----END CERTIFICATE----- diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml index 23f9249..3780129 100644 --- a/src/main/resources/logback-spring.xml +++ b/src/main/resources/logback-spring.xml @@ -28,7 +28,8 @@ - + diff --git a/src/test/kotlin/com/aitrainer/api/test/AppPackageTest.kt b/src/test/kotlin/com/aitrainer/api/test/AppPackageTest.kt index 73ab10d..07ed6a5 100644 --- a/src/test/kotlin/com/aitrainer/api/test/AppPackageTest.kt +++ b/src/test/kotlin/com/aitrainer/api/test/AppPackageTest.kt @@ -182,7 +182,7 @@ class AppPackageTest { val trainingPlanJson: String = record[1] val type = object : TypeToken?>() {}.type val plans: List = gson.fromJson(trainingPlanJson, type) - assertEquals(plans.size,39) + assertEquals(plans.size,40) assertEquals(plans[1].name, "Beginner Men’s workout") assertEquals(plans[1].internalName, "beginner_man") assertEquals(plans[1].free, true)