Skip to content

Commit 3b9283e

Browse files
committed
GH-119: Changed path environment variables to base64 value variables
1 parent 718d873 commit 3b9283e

File tree

11 files changed

+64
-42
lines changed

11 files changed

+64
-42
lines changed

.github/workflows/ci.yaml

+3-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
env:
1717
JDBC_CONNECTION_URL: jdbc:postgresql://localhost:5432/db?user=codegarten&password=changeit
1818
CODEGARTEN_TEST_DB_CONNECTION_STRING: jdbc:postgresql://localhost:5433/db?user=codegarten&password=changeit
19-
CODEGARTEN_GITHUB_APP_PROPERTIES_PATH: secrets-example/github-app-properties.json
20-
CODEGARTEN_GITHUB_APP_PRIVATE_KEY_PATH: secrets-example/gh-app-private-key.pem
21-
CODEGARTEN_CIPHER_KEY_PATH: secrets-example/cipher-key.txt
19+
CODEGARTEN_GITHUB_APP_PROPERTIES: ewogICAgIm5hbWUiOiAiR2l0SHViIEFwcCBOYW1lIiwKICAgICJpZCI6IDEyMzQsCiAgICAiY2xpZW50SWQiOiAiVGhlIENsaWVudCBJRCIsCiAgICAiY2xpZW50U2VjcmV0IjogIlRoZSBDbGllbnQgU2VjcmV0Igp9
20+
CODEGARTEN_GITHUB_APP_PRIVATE_KEY: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlDWEFJQkFBS0JnUUNUSjJJTmU3UURCUkFoRHpFQ096c2Q5ZW9OR3VZd0l2NmNENENFbDdDcDVxTlBtNFBqClBRenQwemE3QTZuN04vVGZHZGJxcVlCWU43RzhDWXQ1VDQzbStEMW9mRmJaeC8wenROU3BkdkNEcGNSdHYzS0IKcjdlM2xOL0dGNkpQd3EyNlJZR0lTNFRwTFBJZkZBVFA4SUFpS3AraHVJMkt4S1MzK3psamdvM3Urd0lEQVFBQgpBb0dBZlVGQWpRbUdxQ3RmRjBTL0NvOHdPc2hmZU5nMHB6U2lWR1E5bUo4bG1QamdlWnArSUthT29zRHVEVEdKCk5uVGkwaVJFYzJuai9UTXE3a3VSbEtqS3QweUk1M29FSzNMbjBMV1dJQUh4cXFjNWg0ZGNmYWRmM2ZpRlhHbmkKSG0vKzU5U2JmTFBaajFCcUhtTFQ2ckpUWFptRkE1ck5TTTgyMzJDbFh1cW1rd0VDUVFER0V5ZXhGOVFSdXBhYwpaMGQ4NUttVFFFOW10NWQ5OERVS1g5WktPSDJPWjhuVzdOZEtrUytBTzlPQTl3L2RiRTcrTTBXcmJ3a05OTTlICnV1L1pzVlhyQWtFQXZqQUpETlhzcll0VFdkR01BMHBRKzFTNlRLdDQ2c0JBdjkxKzRHYVd3WTZodldOMEJzSzgKVHhaWGpwQnNZSG8zeUJNV0wrdEdnN1crWDR2UlBiVTNNUUpBRzFjTmhYNDZnVy8xMWdUVGMwUEV2RlNHSVRGNgpNYUgwVUVoR05keHlTRE8vUW5GU2pqSllFaVV2M244N3ExNkYwTVNXKzBES1NRNWZCaEdoaGJUYW5RSkJBSnE0CjhXUGoxVHdLRUxFTmJGNXc0eGpVZ1F0R3BJUTJDM2NMZHVDUUZTMDZJQkszQ2ZsR0MzUTd0TmRpWHdqTjVQdDcKcTUwb1JxRjRCWHd0ZnZnNHFNRUNRRGM2M1JZeVdndkVGZWFIRExVR1htMlFPa3Z1Q0kreEtpMWF0eHpnVnpXWgpmblhRR2NFZ3VwOGZzZXdhWld0Zy9xWnFUeDAxNklxbTRHcmE3d2gxOTNNPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQoKVGhlIGFib3ZlIGtleSBpcyBtZXJlbHkgYSBkdW1teSBrZXkuIFBsZWFzZSByZXBsYWNlIGl0IHdpdGggeW91ciBvd24u
21+
CODEGARTEN_CIPHER_KEY: cipherkeywith16-24-32bytes
2222
run: code/jvm/gradlew -p code/jvm test

code/js/Dockerfile

-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ COPY secrets ./secrets
88
COPY ./dist ./dist
99
COPY ./views ./views
1010

11-
ENV CG_WEB_CIPHER_KEY_PATH=secrets/cipher-key.txt
12-
1311
EXPOSE 80
1412

1513
ENTRYPOINT [ "node", "./dist/index.js" ]

code/js/lib/user-control.ts

+10-3
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,14 @@
22

33
import { NextFunction, Request, Response } from 'express'
44
import { getAuthenticatedUser } from './repo/services/users'
5-
import { authRoutes } from './repo/api-routes'
65
import { revokeAccessToken } from './repo/services/auth'
76
import { Error } from './types/error-types'
87
import * as crypto from 'crypto'
9-
import * as fs from 'fs'
108

119
const ACCESS_TOKEN_VALIDITY_THRESHOLD = 1000 * 60 * 60 * 24 // 1 day
1210
const ACCESS_TOKEN_COOKIE = 'tok'
1311

14-
const SECRET_KEY = fs.readFileSync(`${process.env.CG_WEB_CIPHER_KEY_PATH}`)
12+
const SECRET_KEY = getSecretKey()
1513
const CIPHER_ALGORITHM = 'aes-256-cbc'
1614

1715
export = function(req: Request, res: Response, next: NextFunction): void {
@@ -91,3 +89,12 @@ function setAccessToken(res: Response, accessToken: AccessToken): void {
9189
function removeAccessToken(res: Response) {
9290
res.expireCookie(ACCESS_TOKEN_COOKIE)
9391
}
92+
93+
function getSecretKey(): string {
94+
const key = process.env.CG_WEB_CIPHER_KEY
95+
if (!key || key.length != 32) {
96+
throw Error('Invalid cipher key specified! The environment variable \'CG_WEB_CIPHER_KEY\' has to have exactly 32 characters.')
97+
}
98+
99+
return key
100+
}

code/js/secrets-example/README.md

-2
This file was deleted.

code/js/secrets-example/cipher-key.txt

-1
This file was deleted.

code/jvm/Dockerfile

-4
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@ COPY ${DEPENDENCY}/META-INF ./server/META-INF
88
COPY secrets ./secrets
99
COPY ${DEPENDENCY}/BOOT-INF/classes ./server
1010

11-
ENV CODEGARTEN_GITHUB_APP_PROPERTIES_PATH=secrets/github-app-properties.json
12-
ENV CODEGARTEN_GITHUB_APP_PRIVATE_KEY_PATH=secrets/gh-app-private-key.pem
13-
ENV CODEGARTEN_CIPHER_KEY_PATH=secrets/cipher-key.txt
14-
1511
EXPOSE 8080
1612

1713
ENTRYPOINT ["java", "-XX:+UseContainerSupport", "-Xmx256m", "-cp", "server:server/lib/*", "org.ionproject.codegarten.CodeGartenApplicationKt"]

code/jvm/src/main/kotlin/org/ionproject/codegarten/CodeGartenApplication.kt

+33-9
Original file line numberDiff line numberDiff line change
@@ -21,29 +21,40 @@ import org.springframework.context.annotation.Bean
2121
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder
2222
import org.springframework.scheduling.annotation.EnableScheduling
2323
import org.springframework.stereotype.Component
24+
import org.springframework.util.Base64Utils
2425
import org.springframework.web.method.support.HandlerMethodArgumentResolver
2526
import org.springframework.web.servlet.config.annotation.InterceptorRegistry
2627
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
27-
import java.io.File
28+
import java.lang.IllegalArgumentException
29+
import java.lang.IllegalStateException
2830
import java.net.URI
2931

3032
@ConfigurationPropertiesScan
3133
@EnableScheduling
3234
@SpringBootApplication
3335
class CodeGartenApplication(private val configProperties: ConfigProperties) {
3436

35-
private val cryptoUtils = CryptoUtils(System.getenv(configProperties.cipherKeyEnv)!!)
37+
private val cryptoUtils: CryptoUtils
38+
39+
init {
40+
val cipherKey = System.getenv(configProperties.cipherKeyEnv)
41+
?: throw IllegalStateException("Missing ${configProperties.cipherKeyEnv} environment variable!")
42+
43+
cryptoUtils = CryptoUtils(cipherKey)
44+
}
3645

3746
@Bean
3847
fun getJdbi(): Jdbi {
3948
val jdbcConnectionString = System.getenv(configProperties.dbJdbcConnectionStringEnv)
4049
val connectionUrl = System.getenv(configProperties.dbUrlConnectionStringEnv)
50+
if (jdbcConnectionString == null && connectionUrl == null)
51+
throw IllegalStateException("Missing ${configProperties.dbJdbcConnectionStringEnv} or ${configProperties.dbUrlConnectionStringEnv} environment variable!")
4152

4253
val connectionString: String =
4354
if (jdbcConnectionString != null)
4455
jdbcConnectionString
4556
else {
46-
val dbUri = URI(connectionUrl!!)
57+
val dbUri = URI(connectionUrl)
4758

4859
val username: String = dbUri.userInfo.split(":")[0]
4960
val password: String = dbUri.userInfo.split(":")[1]
@@ -57,23 +68,36 @@ class CodeGartenApplication(private val configProperties: ConfigProperties) {
5768

5869
@Bean
5970
fun getGithubInterface(): GitHubInterface {
60-
val mapper: ObjectMapper = Jackson2ObjectMapperBuilder().build()
71+
val ghAppPropertiesEnv = System.getenv(configProperties.gitHubAppPropertiesEnv)
72+
?: throw IllegalStateException("Missing ${configProperties.gitHubAppPropertiesEnv} environment variable!")
73+
val ghAppPrivateKeyEnv = System.getenv(configProperties.gitHubAppPrivateKeyEnv)
74+
?: throw IllegalStateException("Missing ${configProperties.gitHubAppPrivateKeyEnv} environment variable!")
75+
76+
val ghAppPropertiesString = try {
77+
Base64Utils.decodeFromString(ghAppPropertiesEnv)
78+
} catch(ex: IllegalArgumentException) {
79+
throw IllegalArgumentException("${configProperties.gitHubAppPropertiesEnv} environment variable is not a valid Base64 string!")
80+
}
81+
82+
val ghAppPrivateKeyString = try {
83+
String(Base64Utils.decodeFromString(ghAppPrivateKeyEnv))
84+
} catch(ex: IllegalArgumentException) {
85+
throw IllegalArgumentException("${configProperties.gitHubAppPrivateKeyEnv} environment variable is not a valid Base64 string!")
86+
}
6187

88+
val mapper: ObjectMapper = Jackson2ObjectMapperBuilder().build()
6289
val ghAppProperties = mapper.readValue(
63-
File(System.getenv(configProperties.gitHubAppPropertiesPathEnv)!!),
90+
ghAppPropertiesString,
6491
GitHubAppProperties::class.java
6592
)
6693

6794
return GitHubInterface(
6895
ghAppProperties,
69-
cryptoUtils.readRsaPrivateKey(
70-
System.getenv(configProperties.gitHubAppPrivateKeyPemPath)!!
71-
),
96+
cryptoUtils.readRsaPrivateKey(ghAppPrivateKeyString),
7297
mapper
7398
)
7499
}
75100

76-
77101
@Bean
78102
fun getCryptoUtils() = cryptoUtils
79103
}

code/jvm/src/main/kotlin/org/ionproject/codegarten/ConfigProperties.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ data class ConfigProperties(
1010
val dbJdbcConnectionStringEnv: String,
1111

1212
// GitHub App Info
13-
val gitHubAppPropertiesPathEnv: String,
14-
val gitHubAppPrivateKeyPemPath: String,
13+
val gitHubAppPropertiesEnv: String,
14+
val gitHubAppPrivateKeyEnv: String,
1515

1616
// Used to encrypt/decrypt access tokens and other sensitive information
1717
val cipherKeyEnv: String

code/jvm/src/main/kotlin/org/ionproject/codegarten/utils/CryptoUtils.kt

+10-10
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ package org.ionproject.codegarten.utils
33
import org.bouncycastle.jce.provider.BouncyCastleProvider
44
import org.bouncycastle.util.io.pem.PemReader
55
import org.springframework.util.Base64Utils
6-
import java.io.File
76
import java.io.FileReader
7+
import java.io.Reader
88
import java.security.Key
99
import java.security.KeyFactory
1010
import java.security.MessageDigest
@@ -29,7 +29,7 @@ data class CodeWrapper(
2929
val expirationDate: OffsetDateTime
3030
)
3131

32-
class CryptoUtils(cipherKeyPath: String) {
32+
class CryptoUtils(cipherKey: String) {
3333

3434
private val validChars: List<Char> = ('a'..'z') + ('A'..'Z') + ('0'..'9')
3535
private val digester = MessageDigest.getInstance("SHA-256")
@@ -38,21 +38,20 @@ class CryptoUtils(cipherKeyPath: String) {
3838
init {
3939
java.security.Security.addProvider(BouncyCastleProvider())
4040

41-
// Read cipher key file content into variable (adding padding if necessary)
42-
val key = File(cipherKeyPath).readText()
41+
// Add padding to cipher key if necessary
4342
var toAssign: ByteArray? = null
4443
for (range in KEY_LENGTH_RANGES) {
45-
if (range.contains(key.length)) {
46-
toAssign = String.format("%1$-" + range.last + "s", key).toByteArray()
44+
if (range.contains(cipherKey.length)) {
45+
toAssign = String.format("%1$-" + range.last + "s", cipherKey).toByteArray()
4746
break
4847
}
4948
}
5049

5150
if (toAssign == null) {
52-
toAssign = key.substring(0, KEY_LENGTH_RANGES.last().last).toByteArray()
51+
toAssign = cipherKey.substring(0, KEY_LENGTH_RANGES.last().last).toByteArray()
5352
}
5453

55-
cipherKey = toAssign
54+
this.cipherKey = toAssign
5655
}
5756

5857
fun generateAuthCode() = generateRandomCode(AUTH_CODE_LENGTH, OffsetDateTime.now().plusMinutes(1))
@@ -111,11 +110,12 @@ class CryptoUtils(cipherKeyPath: String) {
111110
return String(decryptedValue)
112111
}
113112

114-
fun readRsaPrivateKey(filePath: String): Key {
113+
fun readRsaPrivateKey(privateKey: String): Key {
115114
val keyContent: ByteArray
116-
FileReader(filePath).use {
115+
privateKey.reader().use {
117116
keyContent = PemReader(it).readPemObject().content
118117
}
118+
119119
val factory = KeyFactory.getInstance("RSA")
120120
val keySpec = PKCS8EncodedKeySpec(keyContent)
121121
return factory.generatePrivate(keySpec)
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
cg-server.dbUrlConnectionStringEnv=DATABASE_URL
22
cg-server.dbJdbcConnectionStringEnv=JDBC_DATABASE_URL
33

4-
cg-server.gitHubAppPropertiesPathEnv=CODEGARTEN_GITHUB_APP_PROPERTIES_PATH
5-
cg-server.gitHubAppPrivateKeyPemPath=CODEGARTEN_GITHUB_APP_PRIVATE_KEY_PATH
4+
cg-server.gitHubAppPropertiesEnv=CODEGARTEN_GITHUB_APP_PROPERTIES
5+
cg-server.gitHubAppPrivateKeyEnv=CODEGARTEN_GITHUB_APP_PRIVATE_KEY
66

7-
cg-server.cipherKeyEnv=CODEGARTEN_CIPHER_KEY_PATH
7+
cg-server.cipherKeyEnv=CODEGARTEN_CIPHER_KEY
88
server.port=${port:8080}
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
cg-server.dbUrlConnectionStringEnv=DATABASE_URL
22
cg-server.dbJdbcConnectionStringEnv=CODEGARTEN_TEST_DB_CONNECTION_STRING
33

4-
cg-server.gitHubAppPropertiesPathEnv=CODEGARTEN_GITHUB_APP_PROPERTIES_PATH
5-
cg-server.gitHubAppPrivateKeyPemPath=CODEGARTEN_GITHUB_APP_PRIVATE_KEY_PATH
4+
cg-server.gitHubAppPropertiesEnv=CODEGARTEN_GITHUB_APP_PROPERTIES
5+
cg-server.gitHubAppPrivateKeyEnv=CODEGARTEN_GITHUB_APP_PRIVATE_KEY
66

7-
cg-server.cipherKeyEnv=CODEGARTEN_CIPHER_KEY_PATH
7+
cg-server.cipherKeyEnv=CODEGARTEN_CIPHER_KEY
88
server.port=${port:8080}

0 commit comments

Comments
 (0)