Skip to content

Commit

Permalink
do not decrypt passwords on the config page
Browse files Browse the repository at this point in the history
  • Loading branch information
laverya committed Dec 9, 2021
1 parent 0404926 commit 3af3b46
Show file tree
Hide file tree
Showing 11 changed files with 135 additions and 16 deletions.
2 changes: 1 addition & 1 deletion pkg/base/replicated.go
Expand Up @@ -70,7 +70,7 @@ func renderReplicated(u *upstreamtypes.Upstream, renderOptions *RenderOptions) (
versionInfo := template.VersionInfoFromInstallation(renderOptions.Sequence, renderOptions.IsAirgap, kotsKinds.Installation.Spec)
appInfo := template.ApplicationInfo{Slug: renderOptions.AppSlug}

renderedConfig, err := kotsconfig.TemplateConfigObjects(kotsKinds.Config, itemValues, kotsKinds.License, &kotsKinds.KotsApplication, registry, &versionInfo, &appInfo, kotsKinds.IdentityConfig, util.PodNamespace)
renderedConfig, err := kotsconfig.TemplateConfigObjects(kotsKinds.Config, itemValues, kotsKinds.License, &kotsKinds.KotsApplication, registry, &versionInfo, &appInfo, kotsKinds.IdentityConfig, util.PodNamespace, true)
if err != nil {
return nil, nil, errors.Wrap(err, "failed to template config objects")
}
Expand Down
1 change: 1 addition & 0 deletions pkg/base/templates.go
Expand Up @@ -65,6 +65,7 @@ func NewConfigContextTemplateBuilder(u *upstreamtypes.Upstream, renderOptions *R
ApplicationInfo: &appInfo,
IdentityConfig: kotsKinds.IdentityConfig,
Namespace: renderOptions.Namespace,
DecryptValues: true,
}
builder, itemValues, err := template.NewBuilder(builderOptions)
if err != nil {
Expand Down
7 changes: 4 additions & 3 deletions pkg/config/config.go
Expand Up @@ -16,8 +16,8 @@ import (
"k8s.io/client-go/kubernetes/scheme"
)

func TemplateConfigObjects(configSpec *kotsv1beta1.Config, configValues map[string]template.ItemValue, license *kotsv1beta1.License, app *kotsv1beta1.Application, localRegistry template.LocalRegistry, versionInfo *template.VersionInfo, appInfo *template.ApplicationInfo, identityconfig *kotsv1beta1.IdentityConfig, namespace string) (*kotsv1beta1.Config, error) {
templatedString, err := templateConfigObjects(configSpec, configValues, license, app, localRegistry, versionInfo, appInfo, identityconfig, namespace, MarshalConfig)
func TemplateConfigObjects(configSpec *kotsv1beta1.Config, configValues map[string]template.ItemValue, license *kotsv1beta1.License, app *kotsv1beta1.Application, localRegistry template.LocalRegistry, versionInfo *template.VersionInfo, appInfo *template.ApplicationInfo, identityconfig *kotsv1beta1.IdentityConfig, namespace string, decryptValues bool) (*kotsv1beta1.Config, error) {
templatedString, err := templateConfigObjects(configSpec, configValues, license, app, localRegistry, versionInfo, appInfo, identityconfig, namespace, decryptValues, MarshalConfig)
if err != nil {
return nil, errors.Wrap(err, "failed to template config")
}
Expand All @@ -38,7 +38,7 @@ func TemplateConfigObjects(configSpec *kotsv1beta1.Config, configValues map[stri
return config, nil
}

func templateConfigObjects(configSpec *kotsv1beta1.Config, configValues map[string]template.ItemValue, license *kotsv1beta1.License, app *kotsv1beta1.Application, localRegistry template.LocalRegistry, versionInfo *template.VersionInfo, appInfo *template.ApplicationInfo, identityconfig *kotsv1beta1.IdentityConfig, namespace string, marshalFunc func(config *kotsv1beta1.Config) (string, error)) (string, error) {
func templateConfigObjects(configSpec *kotsv1beta1.Config, configValues map[string]template.ItemValue, license *kotsv1beta1.License, app *kotsv1beta1.Application, localRegistry template.LocalRegistry, versionInfo *template.VersionInfo, appInfo *template.ApplicationInfo, identityconfig *kotsv1beta1.IdentityConfig, namespace string, decryptValues bool, marshalFunc func(config *kotsv1beta1.Config) (string, error)) (string, error) {
if configSpec == nil {
return "", nil
}
Expand All @@ -53,6 +53,7 @@ func templateConfigObjects(configSpec *kotsv1beta1.Config, configValues map[stri
ApplicationInfo: appInfo,
IdentityConfig: identityconfig,
Namespace: namespace,
DecryptValues: decryptValues,
}

builder, configVals, err := template.NewBuilder(builderOptions)
Expand Down
4 changes: 2 additions & 2 deletions pkg/config/config_test.go
Expand Up @@ -363,7 +363,7 @@ spec:
configObj, _, _ := decode([]byte(tt.configSpecData), nil, nil)

localRegistry := template.LocalRegistry{}
got, err := templateConfigObjects(configObj.(*kotsv1beta1.Config), tt.configValuesData, license, app, localRegistry, versionInfo, appInfo, nil, "app-namespace", MarshalConfig)
got, err := templateConfigObjects(configObj.(*kotsv1beta1.Config), tt.configValuesData, license, app, localRegistry, versionInfo, appInfo, nil, "app-namespace", false, MarshalConfig)
req.NoError(err)

gotObj, _, err := decode([]byte(got), nil, nil)
Expand All @@ -372,7 +372,7 @@ spec:
req.Equal(wantObj, gotObj)

// compare with oldMarshalConfig results
got, err = templateConfigObjects(configObj.(*kotsv1beta1.Config), tt.configValuesData, license, app, localRegistry, versionInfo, appInfo, nil, "app-namespace", oldMarshalConfig)
got, err = templateConfigObjects(configObj.(*kotsv1beta1.Config), tt.configValuesData, license, app, localRegistry, versionInfo, appInfo, nil, "app-namespace", false, oldMarshalConfig)
if !tt.expectOldFail {
req.NoError(err)

Expand Down
6 changes: 3 additions & 3 deletions pkg/handlers/config.go
Expand Up @@ -242,7 +242,7 @@ func (h *Handler) LiveAppConfig(w http.ResponseWriter, r *http.Request) {

versionInfo := template.VersionInfoFromInstallation(liveAppConfigRequest.Sequence+1, foundApp.IsAirgap, kotsKinds.Installation.Spec) // sequence +1 because the sequence will be incremented on save (and we want the preview to be accurate)
appInfo := template.ApplicationInfo{Slug: foundApp.Slug}
renderedConfig, err := kotsconfig.TemplateConfigObjects(kotsKinds.Config, configValues, appLicense, &kotsKinds.KotsApplication, localRegistry, &versionInfo, &appInfo, kotsKinds.IdentityConfig, util.PodNamespace)
renderedConfig, err := kotsconfig.TemplateConfigObjects(kotsKinds.Config, configValues, appLicense, &kotsKinds.KotsApplication, localRegistry, &versionInfo, &appInfo, kotsKinds.IdentityConfig, util.PodNamespace, false)
if err != nil {
logger.Error(err)
liveAppConfigResponse.Error = "failed to render templates"
Expand Down Expand Up @@ -343,7 +343,7 @@ func (h *Handler) CurrentAppConfig(w http.ResponseWriter, r *http.Request) {

versionInfo := template.VersionInfoFromInstallation(int64(sequence)+1, foundApp.IsAirgap, kotsKinds.Installation.Spec) // sequence +1 because the sequence will be incremented on save (and we want the preview to be accurate)
appInfo := template.ApplicationInfo{Slug: foundApp.Slug}
renderedConfig, err := kotsconfig.TemplateConfigObjects(kotsKinds.Config, configValues, appLicense, &kotsKinds.KotsApplication, localRegistry, &versionInfo, &appInfo, kotsKinds.IdentityConfig, util.PodNamespace)
renderedConfig, err := kotsconfig.TemplateConfigObjects(kotsKinds.Config, configValues, appLicense, &kotsKinds.KotsApplication, localRegistry, &versionInfo, &appInfo, kotsKinds.IdentityConfig, util.PodNamespace, false)
if err != nil {
logger.Error(err)
currentAppConfigResponse.Error = "failed to render templates"
Expand Down Expand Up @@ -811,7 +811,7 @@ func (h *Handler) SetAppConfigValues(w http.ResponseWriter, r *http.Request) {

versionInfo := template.VersionInfoFromInstallation(nextAppSequence, foundApp.IsAirgap, kotsKinds.Installation.Spec) // sequence +1 because the sequence will be incremented on save (and we want the preview to be accurate)
appInfo := template.ApplicationInfo{Slug: foundApp.Slug}
renderedConfig, err := kotsconfig.TemplateConfigObjects(newConfig, configValueMap, kotsKinds.License, &kotsKinds.KotsApplication, localRegistry, &versionInfo, &appInfo, kotsKinds.IdentityConfig, util.PodNamespace)
renderedConfig, err := kotsconfig.TemplateConfigObjects(newConfig, configValueMap, kotsKinds.License, &kotsKinds.KotsApplication, localRegistry, &versionInfo, &appInfo, kotsKinds.IdentityConfig, util.PodNamespace, true)
if err != nil {
setAppConfigValuesResponse.Error = "failed to render templates"
logger.Error(errors.Wrap(err, setAppConfigValuesResponse.Error))
Expand Down
5 changes: 2 additions & 3 deletions pkg/kotsadmconfig/config.go
Expand Up @@ -5,7 +5,6 @@ import (

"github.com/pkg/errors"
kotsv1beta1 "github.com/replicatedhq/kots/kotskinds/apis/kots/v1beta1"
"github.com/replicatedhq/kots/pkg/config"
kotsconfig "github.com/replicatedhq/kots/pkg/config"
"github.com/replicatedhq/kots/pkg/k8sutil"
"github.com/replicatedhq/kots/pkg/kotsutil"
Expand Down Expand Up @@ -60,7 +59,7 @@ func NeedsConfiguration(appSlug string, sequence int64, isAirgap bool, kotsKinds
if err != nil {
return false, errors.Wrap(err, "failed to marshal configvalues spec")
}
configValues, err := config.UnmarshalConfigValuesContent([]byte(configValuesSpec))
configValues, err := kotsconfig.UnmarshalConfigValuesContent([]byte(configValuesSpec))
if err != nil {
log.Error(errors.Wrap(err, "failed to create config values"))
configValues = map[string]template.ItemValue{}
Expand All @@ -78,7 +77,7 @@ func NeedsConfiguration(appSlug string, sequence int64, isAirgap bool, kotsKinds
appInfo := template.ApplicationInfo{Slug: appSlug}

// rendered, err := kotsconfig.TemplateConfig(logger.NewCLILogger(), configSpec, configValuesSpec, licenseSpec, appSpec, identityConfigSpec, localRegistry, util.PodNamespace)
config, err := kotsconfig.TemplateConfigObjects(kotsKinds.Config, configValues, kotsKinds.License, &kotsKinds.KotsApplication, localRegistry, &versionInfo, &appInfo, kotsKinds.IdentityConfig, util.PodNamespace)
config, err := kotsconfig.TemplateConfigObjects(kotsKinds.Config, configValues, kotsKinds.License, &kotsKinds.KotsApplication, localRegistry, &versionInfo, &appInfo, kotsKinds.IdentityConfig, util.PodNamespace, true)
if err != nil {
return false, errors.Wrap(err, "failed to template config")
}
Expand Down
1 change: 1 addition & 0 deletions pkg/render/render.go
Expand Up @@ -97,6 +97,7 @@ func NewBuilder(kotsKinds *kotsutil.KotsKinds, registrySettings registrytypes.Re
VersionInfo: &versionInfo,
IdentityConfig: kotsKinds.IdentityConfig,
Namespace: namespace,
DecryptValues: true,
}
builder, _, err := template.NewBuilder(builderOptions)
return &builder, errors.Wrap(err, "failed to create builder")
Expand Down
3 changes: 2 additions & 1 deletion pkg/template/builder.go
Expand Up @@ -31,6 +31,7 @@ type BuilderOptions struct {
VersionInfo *VersionInfo
IdentityConfig *kotsv1beta1.IdentityConfig
Namespace string
DecryptValues bool
}

// NewBuilder creates a builder with all available contexts.
Expand All @@ -56,7 +57,7 @@ func NewBuilder(opts BuilderOptions) (Builder, map[string]ItemValue, error) {
}

configCtx, err := b.newConfigContext(opts.ConfigGroups, opts.ExistingValues, opts.LocalRegistry,
opts.License, opts.Application, opts.VersionInfo, dockerHubRegistry, slug)
opts.License, opts.Application, opts.VersionInfo, dockerHubRegistry, slug, opts.DecryptValues)
if err != nil {
return Builder{}, nil, errors.Wrap(err, "create config context")
}
Expand Down
6 changes: 4 additions & 2 deletions pkg/template/config_context.go
Expand Up @@ -68,20 +68,22 @@ type ConfigCtx struct {
LocalRegistry LocalRegistry
DockerHubRegistry registry.RegistryOptions
AppSlug string
DecryptValues bool

license *kotsv1beta1.License // Another agument for unifying all these contexts
app *kotsv1beta1.Application
}

// newConfigContext creates and returns a context for template rendering
func (b *Builder) newConfigContext(configGroups []kotsv1beta1.ConfigGroup, existingValues map[string]ItemValue, localRegistry LocalRegistry, license *kotsv1beta1.License, app *kotsv1beta1.Application, info *VersionInfo, dockerHubRegistry registry.RegistryOptions, appSlug string) (*ConfigCtx, error) {
func (b *Builder) newConfigContext(configGroups []kotsv1beta1.ConfigGroup, existingValues map[string]ItemValue, localRegistry LocalRegistry, license *kotsv1beta1.License, app *kotsv1beta1.Application, info *VersionInfo, dockerHubRegistry registry.RegistryOptions, appSlug string, decryptValues bool) (*ConfigCtx, error) {
configCtx := &ConfigCtx{
ItemValues: existingValues,
LocalRegistry: localRegistry,
DockerHubRegistry: dockerHubRegistry,
AppSlug: appSlug,
license: license,
app: app,
DecryptValues: decryptValues,
}

builder := Builder{
Expand All @@ -100,7 +102,7 @@ func (b *Builder) newConfigContext(configGroups []kotsv1beta1.ConfigGroup, exist
configItemsByName[configItem.Name] = configItem

// decrypt password if it exists
if configItem.Type == "password" {
if configItem.Type == "password" && configCtx.DecryptValues {
existingVal, ok := existingValues[configItem.Name]
if ok && existingVal.HasValue() {
val, err := decrypt(existingVal.ValueStr())
Expand Down
115 changes: 114 additions & 1 deletion pkg/template/config_context_test.go
Expand Up @@ -6,16 +6,24 @@ import (

kotsv1beta1 "github.com/replicatedhq/kots/kotskinds/apis/kots/v1beta1"
"github.com/replicatedhq/kots/kotskinds/multitype"
"github.com/replicatedhq/kots/pkg/crypto"
"github.com/replicatedhq/kots/pkg/docker/registry"
"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func TestBuilder_NewConfigContext(t *testing.T) {
err := crypto.NewAESCipher()
require.NoError(t, err)

testValue := "this is a test value to be encrypted"
testValueEncrypted := base64.StdEncoding.EncodeToString(crypto.Encrypt([]byte(testValue)))

type args struct {
configGroups []kotsv1beta1.ConfigGroup
templateContext map[string]ItemValue
license *kotsv1beta1.License
decryptValues bool
}
tests := []struct {
name string
Expand Down Expand Up @@ -358,6 +366,111 @@ func TestBuilder_NewConfigContext(t *testing.T) {
},
},
},
{
name: "chained configOption from password (no decryption)",
args: args{
configGroups: []kotsv1beta1.ConfigGroup{
{
Name: "abc",
Title: "abc",
Description: "abc",
Items: []kotsv1beta1.ConfigItem{
{
Name: "abcItem",
Type: "password",
Title: "abcItem",
Default: multitype.BoolOrString{
Type: multitype.String,
StrVal: "abcItemDefault",
},
Value: multitype.BoolOrString{},
},
{
Name: "childItem1",
Type: "text",
ReadOnly: true,
Value: multitype.BoolOrString{
Type: multitype.String,
StrVal: `hello world repl{{ ConfigOption "abcItem" }}`,
},
},
},
},
},
templateContext: map[string]ItemValue{
"abcItem": {
Value: testValueEncrypted,
},
},
decryptValues: false,
},
want: &ConfigCtx{
AppSlug: "app-slug",
ItemValues: map[string]ItemValue{
"abcItem": {
Value: testValueEncrypted,
Default: "abcItemDefault",
},
"childItem1": {
Value: "hello world " + testValueEncrypted,
Default: "",
},
},
},
},
{
name: "chained configOption from password (with decryption)",
args: args{
configGroups: []kotsv1beta1.ConfigGroup{
{
Name: "abc",
Title: "abc",
Description: "abc",
Items: []kotsv1beta1.ConfigItem{
{
Name: "abcItem",
Type: "password",
Title: "abcItem",
Default: multitype.BoolOrString{
Type: multitype.String,
StrVal: "abcItemDefault",
},
Value: multitype.BoolOrString{},
},
{
Name: "childItem1",
Type: "text",
ReadOnly: true,
Value: multitype.BoolOrString{
Type: multitype.String,
StrVal: `hello world repl{{ ConfigOption "abcItem" }}`,
},
},
},
},
},
templateContext: map[string]ItemValue{
"abcItem": {
Value: testValueEncrypted,
},
},
decryptValues: true,
},
want: &ConfigCtx{
DecryptValues: true,
AppSlug: "app-slug",
ItemValues: map[string]ItemValue{
"abcItem": {
Value: testValue,
Default: "abcItemDefault",
},
"childItem1": {
Value: "hello world " + testValue,
Default: "",
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand All @@ -372,7 +485,7 @@ func TestBuilder_NewConfigContext(t *testing.T) {
builder.AddCtx(StaticCtx{})

localRegistry := LocalRegistry{}
got, err := builder.newConfigContext(tt.args.configGroups, tt.args.templateContext, localRegistry, tt.args.license, nil, nil, registry.RegistryOptions{}, "app-slug")
got, err := builder.newConfigContext(tt.args.configGroups, tt.args.templateContext, localRegistry, tt.args.license, nil, nil, registry.RegistryOptions{}, "app-slug", tt.args.decryptValues)
req.NoError(err)
req.Equal(tt.want, got)
})
Expand Down
1 change: 1 addition & 0 deletions pkg/upstream/replicated.go
Expand Up @@ -629,6 +629,7 @@ func createConfigValues(applicationName string, config *kotsv1beta1.Config, exis
ApplicationInfo: appInfo,
VersionInfo: versionInfo,
IdentityConfig: identityConfig,
DecryptValues: true,
}
builder, _, err := template.NewBuilder(builderOptions)
if err != nil {
Expand Down

0 comments on commit 3af3b46

Please sign in to comment.