authorizer/server/env/persist_env.go

145 lines
4.0 KiB
Go
Raw Normal View History

2021-12-31 08:22:10 +00:00
package env
import (
"encoding/json"
"log"
"os"
"strconv"
2021-12-31 08:22:10 +00:00
"strings"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/db"
2022-01-17 06:02:13 +00:00
"github.com/authorizerdev/authorizer/server/envstore"
2021-12-31 08:22:10 +00:00
"github.com/authorizerdev/authorizer/server/utils"
"github.com/google/uuid"
)
2022-01-17 06:02:13 +00:00
// PersistEnv persists the environment variables to the database
2021-12-31 08:22:10 +00:00
func PersistEnv() error {
env, err := db.Mgr.GetEnv()
2021-12-31 08:22:10 +00:00
// config not found in db
if err != nil {
// AES encryption needs 32 bit key only, so we chop off last 4 characters from 36 bit uuid
hash := uuid.New().String()[:36-4]
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyEncryptionKey, hash)
2021-12-31 08:22:10 +00:00
encodedHash := utils.EncryptB64(hash)
2022-01-17 06:02:13 +00:00
configData, err := json.Marshal(envstore.EnvInMemoryStoreObj.GetEnvStoreClone())
2021-12-31 08:22:10 +00:00
if err != nil {
return err
}
2022-01-19 17:49:20 +00:00
2021-12-31 08:22:10 +00:00
encryptedConfig, err := utils.EncryptAES(configData)
if err != nil {
return err
}
env = db.Env{
Hash: encodedHash,
EnvData: encryptedConfig,
2021-12-31 08:22:10 +00:00
}
db.Mgr.AddEnv(env)
2021-12-31 08:22:10 +00:00
} else {
// decrypt the config data from db
// decryption can be done using the hash stored in db
encryptionKey := env.Hash
2021-12-31 08:22:10 +00:00
decryptedEncryptionKey, err := utils.DecryptB64(encryptionKey)
if err != nil {
return err
}
2022-01-17 06:02:13 +00:00
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyEncryptionKey, decryptedEncryptionKey)
decryptedConfigs, err := utils.DecryptAES(env.EnvData)
2021-12-31 08:22:10 +00:00
if err != nil {
return err
}
// temp store variable
var storeData envstore.Store
2021-12-31 08:22:10 +00:00
err = json.Unmarshal(decryptedConfigs, &storeData)
2021-12-31 08:22:10 +00:00
if err != nil {
return err
}
// if env is changed via env file or OS env
// give that higher preference and update db, but we don't recommend it
hasChanged := false
for key, value := range storeData.StringEnv {
if key != constants.EnvKeyEncryptionKey {
// check only for derivative keys
// No need to check for ENCRYPTION_KEY which special key we use for encrypting config data
// as we have removed it from json
envValue := strings.TrimSpace(os.Getenv(key))
2021-12-31 08:22:10 +00:00
// env is not empty
if envValue != "" {
2021-12-31 08:22:10 +00:00
if value != envValue {
storeData.StringEnv[key] = envValue
2021-12-31 08:22:10 +00:00
hasChanged = true
}
}
}
}
2021-12-31 08:22:10 +00:00
for key, value := range storeData.BoolEnv {
envValue := strings.TrimSpace(os.Getenv(key))
// env is not empty
if envValue != "" {
envValueBool, _ := strconv.ParseBool(envValue)
if value != envValueBool {
storeData.BoolEnv[key] = envValueBool
hasChanged = true
2021-12-31 08:22:10 +00:00
}
}
}
2021-12-31 08:22:10 +00:00
for key, value := range storeData.SliceEnv {
envValue := strings.TrimSpace(os.Getenv(key))
// env is not empty
if envValue != "" {
envStringArr := strings.Split(envValue, ",")
if !utils.IsStringArrayEqual(value, envStringArr) {
storeData.SliceEnv[key] = envStringArr
hasChanged = true
2021-12-31 08:22:10 +00:00
}
}
}
// handle derivative cases like disabling email verification & magic login
// in case SMTP is off but env is set to true
if storeData.StringEnv[constants.EnvKeySmtpHost] == "" || storeData.StringEnv[constants.EnvKeySmtpUsername] == "" || storeData.StringEnv[constants.EnvKeySmtpPassword] == "" || storeData.StringEnv[constants.EnvKeySenderEmail] == "" && storeData.StringEnv[constants.EnvKeySmtpPort] == "" {
if !storeData.BoolEnv[constants.EnvKeyDisableEmailVerification] {
storeData.BoolEnv[constants.EnvKeyDisableEmailVerification] = true
2021-12-31 08:22:10 +00:00
hasChanged = true
}
if !storeData.BoolEnv[constants.EnvKeyDisableMagicLinkLogin] {
storeData.BoolEnv[constants.EnvKeyDisableMagicLinkLogin] = true
2021-12-31 08:22:10 +00:00
hasChanged = true
}
}
envstore.EnvInMemoryStoreObj.UpdateEnvStore(storeData)
2021-12-31 08:22:10 +00:00
if hasChanged {
encryptedConfig, err := utils.EncryptEnvData(storeData)
2021-12-31 11:33:37 +00:00
if err != nil {
return err
}
2021-12-31 08:22:10 +00:00
env.EnvData = encryptedConfig
_, err = db.Mgr.UpdateEnv(env)
2021-12-31 11:33:37 +00:00
if err != nil {
log.Println("error updating config:", err)
return err
}
2021-12-31 08:22:10 +00:00
}
}
return nil
}