Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: unify encKey to encryptionSecret and make .env file readonly in… #5365

Merged
merged 2 commits into from
Jun 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,21 @@ type BlueprintEncryption0904 struct {
}

func (script *encryptBlueprint) Up(basicRes context.BasicRes) errors.Error {
encKey := basicRes.GetConfig(plugin.EncodeKeyEnvStr)
if encKey == "" {
return errors.BadInput.New("invalid encKey")
encryptionSecret := basicRes.GetConfig(plugin.EncodeKeyEnvStr)
if encryptionSecret == "" {
return errors.BadInput.New("invalid encryptionSecret")
}
err := migrationhelper.TransformColumns(
basicRes,
script,
"_devlake_blueprints",
[]string{"plan", "settings"},
func(src *BlueprintEncryption0904) (*BlueprintEncryption0904, errors.Error) {
plan, err := plugin.Encrypt(encKey, src.Plan)
plan, err := plugin.Encrypt(encryptionSecret, src.Plan)
if err != nil {
return nil, err
}
settings, err := plugin.Encrypt(encKey, src.Settings)
settings, err := plugin.Encrypt(encryptionSecret, src.Settings)
if err != nil {
return nil, err
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,17 @@ type PipelineEncryption0904 struct {
}

func (script *encryptPipeline) Up(basicRes context.BasicRes) errors.Error {
encKey := basicRes.GetConfig(plugin.EncodeKeyEnvStr)
if encKey == "" {
return errors.BadInput.New("invalid encKey")
encryptionSecret := basicRes.GetConfig(plugin.EncodeKeyEnvStr)
if encryptionSecret == "" {
return errors.BadInput.New("invalid encryptionSecret")
}
err := migrationhelper.TransformColumns(
basicRes,
script,
"_devlake_pipelines",
[]string{"plan"},
func(src *PipelineEncryption0904) (*PipelineEncryption0904, errors.Error) {
plan, err := plugin.Encrypt(encKey, src.Plan)
plan, err := plugin.Encrypt(encryptionSecret, src.Plan)
if err != nil {
return nil, err
}
Expand Down
8 changes: 4 additions & 4 deletions backend/core/models/migrationscripts/20221221_encrypt_task.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,17 @@ type dstTaskEncryption221221 struct {
}

func (script *encryptTask221221) Up(basicRes context.BasicRes) errors.Error {
encKey := basicRes.GetConfig(plugin.EncodeKeyEnvStr)
if encKey == "" {
return errors.BadInput.New("invalid encKey")
encryptionSecret := basicRes.GetConfig(plugin.EncodeKeyEnvStr)
if encryptionSecret == "" {
return errors.BadInput.New("invalid encryptionSecret")
}
err := migrationhelper.TransformColumns(
basicRes,
script,
"_devlake_tasks",
[]string{"options"},
func(src *srcTaskEncryption221221) (*dstTaskEncryption221221, errors.Error) {
options, err := plugin.Encrypt(encKey, string(src.Options))
options, err := plugin.Encrypt(encryptionSecret, string(src.Options))
if err != nil {
return nil, err
}
Expand Down
24 changes: 12 additions & 12 deletions backend/core/plugin/plugin_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,28 +29,28 @@ import (
"github.com/apache/incubator-devlake/core/utils"
)

const EncodeKeyEnvStr = "ENCODE_KEY"
const EncodeKeyEnvStr = "ENCRYPTION_SECRET"

// TODO: maybe move encryption/decryption into helper?
// AES + Base64 encryption using ENCODE_KEY in .env as key
func Encrypt(encKey, plainText string) (string, errors.Error) {
// AES + Base64 encryption using ENCRYPTION_SECRET in .env as key
func Encrypt(encryptionSecret, plainText string) (string, errors.Error) {
// add suffix to the data part
inputBytes := append([]byte(plainText), 123, 110, 100, 100, 116, 102, 125)
// perform encryption
output, err := AesEncrypt(inputBytes, []byte(encKey))
output, err := AesEncrypt(inputBytes, []byte(encryptionSecret))
if err != nil {
return plainText, err
}
// Return the result after Base64 processing
return base64.StdEncoding.EncodeToString(output), nil
}

// Base64 + AES decryption using ENCODE_KEY in .env as key
func Decrypt(encKey, encryptedText string) (string, errors.Error) {
// Base64 + AES decryption using ENCRYPTION_SECRET in .env as key
func Decrypt(encryptionSecret, encryptedText string) (string, errors.Error) {
// when encryption key is not set
if encKey == "" {
if encryptionSecret == "" {
// return error message
return encryptedText, errors.Default.New("encKey is required")
return encryptedText, errors.Default.New("encryptionSecret is required")
}

// Decode Base64
Expand All @@ -59,7 +59,7 @@ func Decrypt(encKey, encryptedText string) (string, errors.Error) {
return encryptedText, errors.Convert(err1)
}
// perform AES decryption
output, err2 := AesDecrypt(decodingFromBase64, []byte(encKey))
output, err2 := AesDecrypt(decodingFromBase64, []byte(encryptionSecret))
if err2 != nil {
return encryptedText, err2
}
Expand All @@ -75,7 +75,7 @@ func Decrypt(encKey, encryptedText string) (string, errors.Error) {
return string(output), nil
}
}
return "", errors.Default.New("invalid encKey")
return "", errors.Default.New("invalid encryptionSecret")
}

// PKCS7Padding PKCS7 padding
Expand Down Expand Up @@ -139,7 +139,7 @@ func AesDecrypt(crypted, key []byte) ([]byte, errors.Error) {
return origData, nil
}

// RandomEncKey will return a random string of length 128
func RandomEncKey() (string, errors.Error) {
// RandomEncryptionSecret will return a random string of length 128
func RandomEncryptionSecret() (string, errors.Error) {
return utils.RandLetterBytes(128)
}
10 changes: 5 additions & 5 deletions backend/core/plugin/plugin_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,21 @@ func TestEncodeAndDecode(t *testing.T) {
var TestEncode string
var TestDecode string

encKey, _ := RandomEncKey()
encryptionSecret, _ := RandomEncryptionSecret()
// encryption test
TestEncode, err = Encrypt(encKey, TestStr)
TestEncode, err = Encrypt(encryptionSecret, TestStr)
assert.Empty(t, err)

// decrypt test
TestDecode, err = Decrypt(encKey, TestEncode)
TestDecode, err = Decrypt(encryptionSecret, TestEncode)
assert.Empty(t, err)

// Verify decryption result
assert.Equal(t, string(TestDecode), TestStr)
}

func TestEncode(t *testing.T) {
encKey, _ := RandomEncKey()
encryptionSecret, _ := RandomEncryptionSecret()
type args struct {
Input string
}
Expand All @@ -61,7 +61,7 @@ func TestEncode(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := Encrypt(encKey, tt.args.Input)
got, err := Encrypt(encryptionSecret, tt.args.Input)
if (err != nil) != tt.wantErr {
t.Errorf("Encode() error = %v, wantErr %v", err, tt.wantErr)
return
Expand Down
19 changes: 10 additions & 9 deletions backend/helpers/pluginhelper/api/connection_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,23 @@ limitations under the License.
package api

import (
"strconv"

"github.com/apache/incubator-devlake/core/context"
"github.com/apache/incubator-devlake/core/dal"
"github.com/apache/incubator-devlake/core/errors"
"github.com/apache/incubator-devlake/core/log"
"github.com/apache/incubator-devlake/core/models"
plugin "github.com/apache/incubator-devlake/core/plugin"
"github.com/go-playground/validator/v10"
"strconv"
)

// ConnectionApiHelper is used to write the CURD of connection
type ConnectionApiHelper struct {
encKey string
log log.Logger
db dal.Dal
validator *validator.Validate
encryptionSecret string
log log.Logger
db dal.Dal
validator *validator.Validate
}

// NewConnectionHelper creates a ConnectionHelper for connection management
Expand All @@ -45,10 +46,10 @@ func NewConnectionHelper(
vld = validator.New()
}
return &ConnectionApiHelper{
encKey: basicRes.GetConfig(plugin.EncodeKeyEnvStr),
log: basicRes.GetLogger(),
db: basicRes.GetDal(),
validator: vld,
encryptionSecret: basicRes.GetConfig(plugin.EncodeKeyEnvStr),
log: basicRes.GetLogger(),
db: basicRes.GetDal(),
validator: vld,
}
}

Expand Down
10 changes: 5 additions & 5 deletions backend/impls/dalgorm/encdec_serializer.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ var _ schema.SerializerInterface = (*EncDecSerializer)(nil)
// EncDecSerializer is responsible for field encryption/decryption in Application Level
// Ref: https://gorm.io/docs/serializer.html
type EncDecSerializer struct {
encKey string
encryptionSecret string
}

// Scan implements serializer interface
Expand All @@ -52,7 +52,7 @@ func (es *EncDecSerializer) Scan(ctx context.Context, field *schema.Field, dst r
return fmt.Errorf("failed to decrypt value: %#v", dbValue)
}

decrypted, err := plugin.Decrypt(es.encKey, base64str)
decrypted, err := plugin.Decrypt(es.encryptionSecret, base64str)
if err != nil {
return err
}
Expand Down Expand Up @@ -81,10 +81,10 @@ func (es *EncDecSerializer) Value(ctx context.Context, field *schema.Field, dst
default:
return nil, fmt.Errorf("failed to encrypt value: %#v", fieldValue)
}
return plugin.Encrypt(es.encKey, target)
return plugin.Encrypt(es.encryptionSecret, target)
}

// Init the encdec serializer
func Init(encKey string) {
schema.RegisterSerializer("encdec", &EncDecSerializer{encKey: encKey})
func Init(encryptionSecret string) {
schema.RegisterSerializer("encdec", &EncDecSerializer{encryptionSecret: encryptionSecret})
}
17 changes: 3 additions & 14 deletions backend/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,16 @@ package main

import (
"github.com/apache/incubator-devlake/core/config"
"github.com/apache/incubator-devlake/core/errors"
"github.com/apache/incubator-devlake/core/plugin"
_ "github.com/apache/incubator-devlake/core/version"
"github.com/apache/incubator-devlake/server/api"
)

func main() {
v := config.GetConfig()
encKey := v.GetString(plugin.EncodeKeyEnvStr)
if encKey == "" {
var err errors.Error
// Randomly generate a bunch of encryption keys and set them to config
encKey, err = plugin.RandomEncKey()
if err != nil {
panic(err)
}
v.Set(plugin.EncodeKeyEnvStr, encKey)
err = config.WriteConfig(v)
if err != nil {
panic(err)
}
encryptionSecret := v.GetString(plugin.EncodeKeyEnvStr)
if encryptionSecret == "" {
panic("ENCRYPTION_SECRET must be set in .env file")
}
api.CreateApiService()
}
18 changes: 10 additions & 8 deletions backend/test/helper/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@ import (
"encoding/json"
goerror "errors"
"fmt"
"github.com/apache/incubator-devlake/core/dal"
dora "github.com/apache/incubator-devlake/plugins/dora/impl"
org "github.com/apache/incubator-devlake/plugins/org/impl"
remotePlugin "github.com/apache/incubator-devlake/server/services/remote/plugin"
"io"
"math"
"net/http"
Expand All @@ -36,6 +32,11 @@ import (
"testing"
"time"

"github.com/apache/incubator-devlake/core/dal"
dora "github.com/apache/incubator-devlake/plugins/dora/impl"
org "github.com/apache/incubator-devlake/plugins/org/impl"
remotePlugin "github.com/apache/incubator-devlake/server/services/remote/plugin"

"github.com/apache/incubator-devlake/core/config"
corectx "github.com/apache/incubator-devlake/core/context"
"github.com/apache/incubator-devlake/core/errors"
Expand Down Expand Up @@ -215,15 +216,16 @@ func (d *DevlakeClient) RunPlugin(ctx context.Context, pluginName string, plugin

func (d *DevlakeClient) configureEncryption() {
v := config.GetConfig()
encKey := v.GetString(plugin.EncodeKeyEnvStr)
if encKey == "" {
encryptionSecret := v.GetString(plugin.EncodeKeyEnvStr)
// only test environment should have this set
if encryptionSecret == "" {
var err errors.Error
// Randomly generate a bunch of encryption keys and set them to config
encKey, err = plugin.RandomEncKey()
encryptionSecret, err = plugin.RandomEncryptionSecret()
if err != nil {
panic(err)
}
v.Set(plugin.EncodeKeyEnvStr, encKey)
v.Set(plugin.EncodeKeyEnvStr, encryptionSecret)
err = config.WriteConfig(v)
if err != nil {
panic(err)
Expand Down
2 changes: 1 addition & 1 deletion env.example
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ DISABLED_REMOTE_PLUGINS=
##########################
# Sensitive information encryption key
##########################
ENCODE_KEY=
ENCRYPTION_SECRET=

##########################
# Set if skip verify and connect with out trusted certificate when use https
Expand Down