localconfig/creds.go
2023-01-28 13:40:19 +01:00

106 lines
2.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package localconfig
import (
"bufio"
"encoding/json"
"errors"
"fmt"
"math/rand"
"os"
"strings"
"time"
"github.com/ProtonMail/gopenpgp/v2/helper"
"github.com/howeyc/gopass"
)
// Creds is user credentials
type Creds struct {
Login string
Password string
}
func randomString(n int) string {
rand.Seed(time.Now().UnixNano())
var letters = []rune("яшертёыуиопющэъасдфгчйкльжзхцвбнмabéàèùàçïôÖcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789&([-|_@])=+§!:;,*%$£µ")
s := make([]rune, n)
for i := range s {
s[i] = letters[rand.Intn(len(letters))]
}
return string(s)
}
func loadRootKey() []byte {
rkpath := getConfig("rk")
rk, err := os.ReadFile(rkpath)
if err != nil {
rk = []byte(randomString(64))
os.WriteFile(rkpath, rk, 0600)
}
return rk
}
func (creds *Creds) Exists(filename string) bool {
if _, err := os.Stat(getConfig(filename)); err == nil {
return true
} else if errors.Is(err, os.ErrNotExist) {
return false
} else {
return false
}
}
// Init will initalize login/password
func (creds *Creds) Init(filename string) {
fmt.Print("Enter login: ")
var login string
reader := bufio.NewReader(os.Stdin)
login, _ = reader.ReadString('\n')
creds.Login = strings.Trim(login, "\r\n")
if login != "" {
fmt.Print("Enter password:")
bytePassword, _ := gopass.GetPasswd()
silentPassword := string(bytePassword)
if silentPassword != "" {
creds.Password = silentPassword
b, _ := json.Marshal(creds)
fmt.Println("Writing credentials to : " + getConfig(filename))
armor, _ := helper.EncryptMessageWithPassword(loadRootKey(), string(b))
os.WriteFile(getConfig(filename), []byte(armor), 0600)
}
}
}
// Pw : update password
func (creds *Creds) NewPw(filename string) {
fmt.Print("Enter new password:")
bytePassword, _ := gopass.GetPasswd()
silentPassword := string(bytePassword)
if silentPassword != "" {
creds.Password = silentPassword
b, _ := json.Marshal(creds)
armor, _ := helper.EncryptMessageWithPassword(loadRootKey(), string(b))
os.WriteFile(getConfig(filename), []byte(armor), 0600)
}
}
// Load credentials if available or creates them
func (creds *Creds) Load(filename string) error {
indata, err := os.ReadFile(getConfig(filename))
if err != nil {
creds.Init(filename)
return nil
}
pass, err := helper.DecryptMessageWithPassword(loadRootKey(), string(indata))
if err != nil {
creds.Init(filename)
return nil
}
err = json.Unmarshal([]byte(pass), &creds)
if err != nil {
creds.Init(filename)
return nil
}
return nil
}