fix: import Cloudflare Secret credentials
This commit is contained in:
parent
f17097ecae
commit
a08eb8616d
|
|
@ -1,6 +1,7 @@
|
||||||
package cloudflare
|
package cloudflare
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
|
|
@ -53,9 +54,42 @@ func IsLegacyRunTokenState(values map[string]string) bool {
|
||||||
func ReadCredentialsFile(path string) (Credentials, error) {
|
func ReadCredentialsFile(path string) (Credentials, error) {
|
||||||
contents, err := os.ReadFile(path)
|
contents, err := os.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Credentials{}, errors.New("read Cloudflare credentials file")
|
return Credentials{}, errors.New("invalid Cloudflare credentials file")
|
||||||
}
|
}
|
||||||
return parseCredentials(contents)
|
if credentials, err := parseCredentials(contents); err == nil {
|
||||||
|
return credentials, nil
|
||||||
|
}
|
||||||
|
credentials, err := credentialsFromSecret(contents)
|
||||||
|
if err != nil {
|
||||||
|
return Credentials{}, errors.New("invalid Cloudflare credentials file")
|
||||||
|
}
|
||||||
|
return credentials, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func credentialsFromSecret(contents []byte) (Credentials, error) {
|
||||||
|
var secret struct {
|
||||||
|
APIVersion string `yaml:"apiVersion"`
|
||||||
|
Kind string `yaml:"kind"`
|
||||||
|
StringData map[string]string `yaml:"stringData"`
|
||||||
|
Data map[string]string `yaml:"data"`
|
||||||
|
}
|
||||||
|
decoder := yaml.NewDecoder(strings.NewReader(string(contents)))
|
||||||
|
if err := decoder.Decode(&secret); err != nil || decoder.Decode(&struct{}{}) != io.EOF || secret.APIVersion != "v1" || secret.Kind != "Secret" {
|
||||||
|
return Credentials{}, errors.New("invalid Secret")
|
||||||
|
}
|
||||||
|
plaintext, inStringData := secret.StringData[credentialsKey]
|
||||||
|
encoded, inData := secret.Data[credentialsKey]
|
||||||
|
if inStringData == inData {
|
||||||
|
return Credentials{}, errors.New("missing Secret credentials")
|
||||||
|
}
|
||||||
|
if inStringData {
|
||||||
|
return parseCredentials([]byte(plaintext))
|
||||||
|
}
|
||||||
|
decoded, err := base64.StdEncoding.DecodeString(encoded)
|
||||||
|
if err != nil {
|
||||||
|
return Credentials{}, errors.New("invalid Secret credentials")
|
||||||
|
}
|
||||||
|
return parseCredentials(decoded)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRoute(hostname, service string) (Route, error) {
|
func NewRoute(hostname, service string) (Route, error) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package cloudflare
|
package cloudflare
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/base64"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
@ -31,18 +32,31 @@ func TestStoredTunnelRejectsLegacyOrPartialState(t *testing.T) {
|
||||||
|
|
||||||
func TestReadCredentialsFileRequiresKnownFields(t *testing.T) {
|
func TestReadCredentialsFileRequiresKnownFields(t *testing.T) {
|
||||||
path := filepath.Join(t.TempDir(), "credentials.json")
|
path := filepath.Join(t.TempDir(), "credentials.json")
|
||||||
if err := os.WriteFile(path, []byte(`{"AccountTag":"account","TunnelSecret":"secret","TunnelID":"tunnel"}`), 0600); err != nil {
|
raw := `{"AccountTag":"account","TunnelSecret":"secret","TunnelID":"tunnel"}`
|
||||||
t.Fatal(err)
|
for _, contents := range []string{
|
||||||
}
|
raw,
|
||||||
credentials, err := ReadCredentialsFile(path)
|
"apiVersion: v1\nkind: Secret\nstringData:\n credentials.json: |\n " + raw + "\n",
|
||||||
if err != nil || credentials.TunnelID != "tunnel" {
|
"apiVersion: v1\nkind: Secret\ndata:\n credentials.json: " + base64.StdEncoding.EncodeToString([]byte(raw)) + "\n",
|
||||||
t.Fatal("valid credential file was not accepted")
|
} {
|
||||||
|
if err := os.WriteFile(path, []byte(contents), 0600); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
credentials, err := ReadCredentialsFile(path)
|
||||||
|
if err != nil || credentials.TunnelID != "tunnel" {
|
||||||
|
t.Fatal("supported credential file was not accepted")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err := os.WriteFile(path, []byte(`{"AccountTag":"account","TunnelSecret":"secret","TunnelID":"tunnel","extra":"value"}`), 0600); err != nil {
|
if err := os.WriteFile(path, []byte(`{"AccountTag":"account","TunnelSecret":"secret","TunnelID":"tunnel","extra":"value"}`), 0600); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if _, err := ReadCredentialsFile(path); err == nil {
|
if _, err := ReadCredentialsFile(path); err == nil || err.Error() != "invalid Cloudflare credentials file" {
|
||||||
t.Fatal("credential file with unknown fields was accepted")
|
t.Fatal("credential file with unknown fields did not return a safe error")
|
||||||
|
}
|
||||||
|
if err := os.WriteFile(path, []byte("apiVersion: v1\nkind: Secret\ndata: {}\n"), 0600); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, err := ReadCredentialsFile(path); err == nil || err.Error() != "invalid Cloudflare credentials file" {
|
||||||
|
t.Fatal("Secret without credentials did not return a safe error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue