Files
cloudsave/cmd/cli/tools/prompt/credentials/credentials.go
Aurélie DELHAIE 46f312078d
Some checks failed
CloudSave/pipeline/head Something is wrong with the build of this commit
fix sec
2025-09-07 01:31:14 +02:00

124 lines
2.3 KiB
Go

package credentials
import (
"bufio"
"encoding/json"
"errors"
"fmt"
"os"
"path/filepath"
"strings"
"golang.org/x/term"
)
type (
credential struct {
Username string `json:"username"`
Password string `json:"password"`
}
credentialsStore struct {
Store map[string]credential `json:"store"`
}
)
var (
datastorePath string
)
func init() {
roaming, err := os.UserConfigDir()
if err != nil {
panic("failed to get user config path: " + err.Error())
}
datastorePath = filepath.Join(roaming, "cloudsave")
}
func Read(server string) (string, string, error) {
var err error
store, err := load()
if err == nil {
if c, ok := store[server]; ok {
return c.Username, c.Password, nil
}
}
fmt.Print("Enter username: ")
reader := bufio.NewReader(os.Stdin)
username, _ := reader.ReadString('\n')
username = strings.TrimSpace(username)
fmt.Printf("password for %s: ", username)
password, err := term.ReadPassword(int(os.Stdin.Fd()))
if err != nil {
return "", "", err
}
fmt.Println()
return username, string(password), nil
}
func Login(username, password, server string) error {
store, err := load()
if err != nil {
return err
}
store[server] = credential{
Username: username,
Password: password,
}
return save(store)
}
func Logout(server string) error {
store, err := load()
if err != nil {
return err
}
delete(store, server)
return save(store)
}
func save(store map[string]credential) error {
c := credentialsStore{
Store: store,
}
f, err := os.OpenFile(filepath.Clean(filepath.Join(datastorePath, "credential.json")), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600)
if err != nil {
return fmt.Errorf("failed to open datastore: %w", err)
}
defer f.Close()
e := json.NewEncoder(f)
if err := e.Encode(c); err != nil {
return fmt.Errorf("failed to encode data: %w", err)
}
return nil
}
func load() (map[string]credential, error) {
f, err := os.OpenFile(filepath.Clean(filepath.Join(datastorePath, "credential.json")), os.O_RDONLY, 0)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
return make(map[string]credential), nil
}
return nil, fmt.Errorf("failed to open datastore: %w", err)
}
defer f.Close()
var c credentialsStore
d := json.NewDecoder(f)
if err := d.Decode(&c); err != nil {
return nil, fmt.Errorf("failed to decode data: %w", err)
}
return c.Store, nil
}