github.com/tooploox/oya@v0.0.21-0.20230524103240-1cda1861aad6/pkg/secrets/secrets.go (about)

     1  package secrets
     2  
     3  import (
     4  	"encoding/json"
     5  	"io/ioutil"
     6  	"os"
     7  	"os/exec"
     8  )
     9  
    10  type KeyPair struct {
    11  	Public      string `json:"public_key"`
    12  	Private     string `json:"private_key"`
    13  	Fingerprint string `json:"fingerprint"`
    14  }
    15  
    16  func Init(email, name, desc string) (KeyPair, error) {
    17  	return generatePGPKeyPair(email, name, desc)
    18  }
    19  
    20  func Decrypt(path string) ([]byte, bool, error) {
    21  	if ok, err := isSopsFile(path); !ok || err != nil {
    22  		return nil, false, err
    23  	}
    24  
    25  	var output []byte
    26  	if _, err := os.Stat(path); err != nil {
    27  		if os.IsNotExist(err) {
    28  			return output, false, ErrNoSecretsFile{Path: path}
    29  		} else {
    30  			return output, false, err
    31  		}
    32  	}
    33  	decryptCmd := exec.Command("sops", "-d", path)
    34  	decrypted, err := decryptCmd.CombinedOutput()
    35  	if err != nil {
    36  		return output, false,
    37  			ErrSecretsFailure{Path: path, Err: err}
    38  	}
    39  	return decrypted, true, nil
    40  }
    41  
    42  func Encrypt(inputPath, outputPath string) error {
    43  	if alreadyEncrypted(inputPath) {
    44  		return ErrSecretsAlreadyEncrypted{Path: inputPath}
    45  	}
    46  	cmd := exec.Command("sops", "-e", inputPath)
    47  	encoded, err := cmd.CombinedOutput()
    48  	if err != nil {
    49  		return ErrSecretsFailure{Path: inputPath, Err: err}
    50  	}
    51  	fi, err := os.Stat(inputPath)
    52  	if err != nil {
    53  		return err
    54  	}
    55  	err = ioutil.WriteFile(outputPath, encoded, fi.Mode())
    56  	if err != nil {
    57  		return err
    58  	}
    59  	return nil
    60  }
    61  
    62  func ViewCmd(filename string) *exec.Cmd {
    63  	return exec.Command("sops", filename)
    64  }
    65  
    66  func isSopsFile(path string) (bool, error) {
    67  	jsonFile, err := os.Open(path)
    68  	if err != nil {
    69  		return false, err
    70  	}
    71  	dec := json.NewDecoder(jsonFile)
    72  	var v map[string]interface{}
    73  	if err := dec.Decode(&v); err != nil {
    74  		return false, nil // Yes, ignoring error.
    75  	}
    76  	_, ok := v["sops"]
    77  	return ok, nil
    78  }
    79  
    80  func alreadyEncrypted(path string) bool {
    81  	// Trying to decrypt and check if succeed
    82  	cmd := exec.Command("sops", "-d", path)
    83  	if err := cmd.Run(); err != nil {
    84  		return false
    85  	}
    86  	return true
    87  }