@ -18,6 +18,8 @@ package engine
import (
import (
"bytes"
"bytes"
"crypto/sha1"
"encoding/base64"
"encoding/json"
"encoding/json"
"errors"
"errors"
"fmt"
"fmt"
@ -31,6 +33,7 @@ import (
"github.com/BurntSushi/toml"
"github.com/BurntSushi/toml"
"github.com/Masterminds/sprig/v3"
"github.com/Masterminds/sprig/v3"
"golang.org/x/crypto/bcrypt"
"sigs.k8s.io/yaml"
"sigs.k8s.io/yaml"
goYaml "sigs.k8s.io/yaml/goyaml.v3"
goYaml "sigs.k8s.io/yaml/goyaml.v3"
)
)
@ -53,6 +56,10 @@ func funcMap() template.FuncMap {
delete ( f , "env" )
delete ( f , "env" )
delete ( f , "expandenv" )
delete ( f , "expandenv" )
// Override the sprig "htpasswd" function so it accepts an optional
// third argument to select the hash algorithm.
f [ "htpasswd" ] = htpasswd
// Add some extra functionality
// Add some extra functionality
extra := template . FuncMap {
extra := template . FuncMap {
"toToml" : toTOML ,
"toToml" : toTOML ,
@ -99,6 +106,38 @@ func funcMap() template.FuncMap {
return f
return f
}
}
// htpasswd takes a username and password and returns an htpasswd entry. It
// extends the sprig-provided function (see https://github.com/helm/helm/issues/31924)
// by accepting an optional third argument to select the hash algorithm.
//
// Supported algorithms are "bcrypt" (the default, with the same cost as
// sprig) and "sha" ({SHA} base64-encoded SHA-1). Unlike a panic, invalid
// input is reported by returning a descriptive error string.
func htpasswd ( username , password string , algorithm ... string ) string {
if strings . Contains ( username , ":" ) {
return fmt . Sprintf ( "invalid username: %s" , username )
}
alg := "bcrypt"
if len ( algorithm ) > 0 {
alg = algorithm [ 0 ]
}
switch alg {
case "bcrypt" :
hash , err := bcrypt . GenerateFromPassword ( [ ] byte ( password ) , bcrypt . DefaultCost )
if err != nil {
return fmt . Sprintf ( "failed to encrypt string with bcrypt: %s" , err )
}
return fmt . Sprintf ( "%s:%s" , username , hash )
case "sha" :
h := sha1 . Sum ( [ ] byte ( password ) )
return fmt . Sprintf ( "%s:{SHA}%s" , username , base64 . StdEncoding . EncodeToString ( h [ : ] ) )
default :
return fmt . Sprintf ( "invalid hash algorithm: %s" , alg )
}
}
// toYAML takes an interface, marshals it to yaml, and returns a string. It will
// toYAML takes an interface, marshals it to yaml, and returns a string. It will
// always return a string, even on marshal error (empty string).
// always return a string, even on marshal error (empty string).
//
//