Merge pull request #6207 from hashicorp/llb-password-credential-type
Password credential type
This commit is contained in:
66 files changed
+5784
-947
No files matched your search
@@ -12,6 +12,7 @@ import (
|
||||
|
||||
const (
|
||||
usernamePasswordCredentialType = "username_password"
|
||||
passwordCredentialType = "password"
|
||||
sshPrivateKeyCredentialType = "ssh_private_key"
|
||||
)
|
||||
|
||||
@@ -26,6 +27,16 @@ type UsernamePassword struct {
|
||||
Consumed bool
|
||||
}
|
||||
|
||||
// Password contains a password credential
|
||||
type Password struct {
|
||||
Password string `mapstructure:"password"`
|
||||
|
||||
Raw *targets.SessionCredential
|
||||
// Consumed can be set by the caller to indicate that the credential has
|
||||
// been used, e.g. displayed to the user
|
||||
Consumed bool
|
||||
}
|
||||
|
||||
// SshPrivateKey contains the username and private key with optional passphrase
|
||||
// for the key
|
||||
type SshPrivateKey struct {
|
||||
@@ -41,6 +52,7 @@ type SshPrivateKey struct {
|
||||
|
||||
type Credentials struct {
|
||||
UsernamePassword []UsernamePassword
|
||||
Password []Password
|
||||
SshPrivateKey []SshPrivateKey
|
||||
// Unspecified are credentials that do not match one of the types above
|
||||
Unspecified []*targets.SessionCredential
|
||||
@@ -62,6 +74,11 @@ func (c Credentials) UnconsumedSessionCredentials() []*targets.SessionCredential
|
||||
out = append(out, c.Raw)
|
||||
}
|
||||
}
|
||||
for _, c := range c.Password {
|
||||
if !c.Consumed {
|
||||
out = append(out, c.Raw)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
@@ -76,6 +93,7 @@ func ParseCredentials(creds []*targets.SessionCredential) (Credentials, error) {
|
||||
}
|
||||
|
||||
var upCred UsernamePassword
|
||||
var pCred Password
|
||||
var spkCred SshPrivateKey
|
||||
switch cred.CredentialSource.CredentialType {
|
||||
case usernamePasswordCredentialType:
|
||||
@@ -90,6 +108,18 @@ func ParseCredentials(creds []*targets.SessionCredential) (Credentials, error) {
|
||||
continue
|
||||
}
|
||||
|
||||
case passwordCredentialType:
|
||||
// Decode attributes from credential struct
|
||||
if err := mapstructure.Decode(cred.Credential, &pCred); err != nil {
|
||||
return Credentials{}, err
|
||||
}
|
||||
|
||||
if pCred.Password != "" {
|
||||
pCred.Raw = cred
|
||||
out.Password = append(out.Password, pCred)
|
||||
continue
|
||||
}
|
||||
|
||||
case sshPrivateKeyCredentialType:
|
||||
// Decode attributes from credential struct
|
||||
if err := mapstructure.Decode(cred.Credential, &spkCred); err != nil {
|
||||
@@ -116,6 +146,16 @@ func ParseCredentials(creds []*targets.SessionCredential) (Credentials, error) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Attempt unmarshaling into password creds
|
||||
if err := mapstructure.Decode(cred.Secret.Decoded, &pCred); err != nil {
|
||||
return Credentials{}, err
|
||||
}
|
||||
if pCred.Password != "" {
|
||||
pCred.Raw = cred
|
||||
out.Password = append(out.Password, pCred)
|
||||
continue
|
||||
}
|
||||
|
||||
// Attempt unmarshaling into ssh private key creds
|
||||
if err := mapstructure.Decode(cred.Secret.Decoded, &spkCred); err != nil {
|
||||
return Credentials{}, err
|
||||
|
||||
@@ -29,6 +29,15 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
typedPassword = &targets.SessionCredential{
|
||||
CredentialSource: &targets.CredentialSource{
|
||||
CredentialType: passwordCredentialType,
|
||||
},
|
||||
Credential: map[string]any{
|
||||
"password": "pass",
|
||||
},
|
||||
}
|
||||
|
||||
typedSshPrivateKey = &targets.SessionCredential{
|
||||
CredentialSource: &targets.CredentialSource{
|
||||
CredentialType: sshPrivateKeyCredentialType,
|
||||
@@ -75,6 +84,17 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
vaultPassword = &targets.SessionCredential{
|
||||
CredentialSource: &targets.CredentialSource{
|
||||
Type: vaultGenericLibrarySubtype,
|
||||
},
|
||||
Secret: &targets.SessionSecret{
|
||||
Decoded: map[string]any{
|
||||
"password": "vault-decoded-pass",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
vaultSshPrivateKey = &targets.SessionCredential{
|
||||
CredentialSource: &targets.CredentialSource{
|
||||
Type: vaultGenericLibrarySubtype,
|
||||
@@ -119,6 +139,17 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
staticPassword = &targets.SessionCredential{
|
||||
CredentialSource: &targets.CredentialSource{
|
||||
Type: staticSubtype,
|
||||
},
|
||||
Secret: &targets.SessionSecret{
|
||||
Decoded: map[string]any{
|
||||
"password": "static-decoded-pass",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
staticSshPrivateKey = &targets.SessionCredential{
|
||||
CredentialSource: &targets.CredentialSource{
|
||||
Type: staticSubtype,
|
||||
@@ -215,6 +246,21 @@ func Test_parseCredentials(t *testing.T) {
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "password-typed",
|
||||
creds: []*targets.SessionCredential{
|
||||
typedPassword,
|
||||
},
|
||||
wantCreds: Credentials{
|
||||
Password: []Password{
|
||||
{
|
||||
Password: "pass",
|
||||
Raw: typedPassword,
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "ssh-private-key-typed",
|
||||
creds: []*targets.SessionCredential{
|
||||
@@ -247,6 +293,21 @@ func Test_parseCredentials(t *testing.T) {
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "vault-password-decoded",
|
||||
creds: []*targets.SessionCredential{
|
||||
vaultPassword,
|
||||
},
|
||||
wantCreds: Credentials{
|
||||
Password: []Password{
|
||||
{
|
||||
Password: "vault-decoded-pass",
|
||||
Raw: vaultPassword,
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "vault-private-key-decoded",
|
||||
creds: []*targets.SessionCredential{
|
||||
@@ -343,6 +404,21 @@ func Test_parseCredentials(t *testing.T) {
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "static-password-decoded",
|
||||
creds: []*targets.SessionCredential{
|
||||
staticPassword,
|
||||
},
|
||||
wantCreds: Credentials{
|
||||
Password: []Password{
|
||||
{
|
||||
Password: "static-decoded-pass",
|
||||
Raw: staticPassword,
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "static-private-key-decoded",
|
||||
creds: []*targets.SessionCredential{
|
||||
@@ -388,7 +464,7 @@ func Test_parseCredentials(t *testing.T) {
|
||||
creds: []*targets.SessionCredential{
|
||||
staticSshPrivateKey, UnspecifiedCred1, vaultSshPrivateKey, typedUsernamePassword,
|
||||
UnspecifiedCred, vaultUsernamePassword, typedSshPrivateKey, staticUsernamePassword,
|
||||
staticKv,
|
||||
staticKv, typedPassword, vaultPassword, staticPassword,
|
||||
},
|
||||
wantCreds: Credentials{
|
||||
SshPrivateKey: []SshPrivateKey{
|
||||
@@ -425,6 +501,20 @@ func Test_parseCredentials(t *testing.T) {
|
||||
Raw: typedUsernamePassword,
|
||||
},
|
||||
},
|
||||
Password: []Password{
|
||||
{
|
||||
Password: "static-decoded-pass",
|
||||
Raw: staticPassword,
|
||||
},
|
||||
{
|
||||
Password: "vault-decoded-pass",
|
||||
Raw: vaultPassword,
|
||||
},
|
||||
{
|
||||
Password: "pass",
|
||||
Raw: typedPassword,
|
||||
},
|
||||
},
|
||||
Unspecified: []*targets.SessionCredential{
|
||||
UnspecifiedCred, UnspecifiedCred1, staticKv,
|
||||
},
|
||||
@@ -447,6 +537,7 @@ func Test_parseCredentials(t *testing.T) {
|
||||
assert.ElementsMatch(tt.wantCreds.UsernamePassword, creds.UsernamePassword)
|
||||
assert.ElementsMatch(tt.wantCreds.SshPrivateKey, creds.SshPrivateKey)
|
||||
assert.ElementsMatch(tt.wantCreds.Unspecified, creds.Unspecified)
|
||||
assert.ElementsMatch(tt.wantCreds.Password, creds.Password)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -507,6 +598,29 @@ func Test_unconsumedSessionCredentials(t *testing.T) {
|
||||
},
|
||||
wantCreds: nil,
|
||||
},
|
||||
{
|
||||
name: "p",
|
||||
creds: Credentials{
|
||||
Password: []Password{
|
||||
{
|
||||
Raw: vaultPassword,
|
||||
},
|
||||
},
|
||||
},
|
||||
wantCreds: []*targets.SessionCredential{vaultPassword},
|
||||
},
|
||||
{
|
||||
name: "p-consumed",
|
||||
creds: Credentials{
|
||||
Password: []Password{
|
||||
{
|
||||
Raw: vaultPassword,
|
||||
Consumed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
wantCreds: nil,
|
||||
},
|
||||
{
|
||||
name: "Unspecified",
|
||||
creds: Credentials{
|
||||
@@ -542,10 +656,23 @@ func Test_unconsumedSessionCredentials(t *testing.T) {
|
||||
Consumed: true,
|
||||
},
|
||||
},
|
||||
Password: []Password{
|
||||
{
|
||||
Raw: staticPassword,
|
||||
},
|
||||
{
|
||||
Raw: vaultPassword,
|
||||
},
|
||||
{
|
||||
Raw: typedPassword,
|
||||
Consumed: true,
|
||||
},
|
||||
},
|
||||
Unspecified: []*targets.SessionCredential{UnspecifiedCred, UnspecifiedCred1},
|
||||
},
|
||||
wantCreds: []*targets.SessionCredential{
|
||||
vaultSshPrivateKey, typedSshPrivateKey, vaultUsernamePassword, UnspecifiedCred, UnspecifiedCred1,
|
||||
staticPassword, vaultPassword,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -579,6 +706,20 @@ func Test_unconsumedSessionCredentials(t *testing.T) {
|
||||
Consumed: true,
|
||||
},
|
||||
},
|
||||
Password: []Password{
|
||||
{
|
||||
Raw: staticPassword,
|
||||
Consumed: true,
|
||||
},
|
||||
{
|
||||
Raw: vaultPassword,
|
||||
Consumed: true,
|
||||
},
|
||||
{
|
||||
Raw: typedPassword,
|
||||
Consumed: true,
|
||||
},
|
||||
},
|
||||
Unspecified: []*targets.SessionCredential{UnspecifiedCred, UnspecifiedCred1},
|
||||
},
|
||||
wantCreds: []*targets.SessionCredential{
|
||||
@@ -610,11 +751,23 @@ func Test_unconsumedSessionCredentials(t *testing.T) {
|
||||
Raw: typedUsernamePassword,
|
||||
},
|
||||
},
|
||||
Password: []Password{
|
||||
{
|
||||
Raw: staticPassword,
|
||||
},
|
||||
{
|
||||
Raw: vaultPassword,
|
||||
},
|
||||
{
|
||||
Raw: typedPassword,
|
||||
},
|
||||
},
|
||||
Unspecified: []*targets.SessionCredential{UnspecifiedCred, UnspecifiedCred1},
|
||||
},
|
||||
wantCreds: []*targets.SessionCredential{
|
||||
staticSshPrivateKey, UnspecifiedCred1, vaultSshPrivateKey, typedUsernamePassword,
|
||||
UnspecifiedCred, vaultUsernamePassword, typedSshPrivateKey, staticUsernamePassword,
|
||||
staticPassword, vaultPassword, typedPassword,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user