mirror of
https://github.com/rwinkhart/MUTN.git
synced 2026-08-28 04:46:41 -04:00
Implement ReadConfig for reading ~/.config/libmutton/libmutton.ini
This commit is contained in:
@@ -2,9 +2,13 @@ module github.com/rwinkhart/MUTN
|
||||
|
||||
go 1.22.0
|
||||
|
||||
require golang.org/x/crypto v0.20.0
|
||||
require (
|
||||
golang.org/x/crypto v0.20.0
|
||||
gopkg.in/ini.v1 v1.67.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/stretchr/testify v1.8.4 // indirect
|
||||
golang.org/x/sys v0.17.0 // indirect
|
||||
golang.org/x/term v0.17.0 // indirect
|
||||
)
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg=
|
||||
golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ=
|
||||
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"github.com/rwinkhart/MUTN/src/cli"
|
||||
"github.com/rwinkhart/MUTN/src/offline"
|
||||
"os"
|
||||
)
|
||||
|
||||
@@ -34,5 +35,8 @@ func main() {
|
||||
cli.HelpMain()
|
||||
|
||||
}
|
||||
} else if argsCount > 1 {
|
||||
// load config (libmutton.ini)
|
||||
offline.ReadConfig()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ var (
|
||||
|
||||
// global constants used across multiple files
|
||||
const (
|
||||
ansiReset = "\033[0m"
|
||||
ansiBold = "\033[1m"
|
||||
ansiBlackOnWhite = "\033[38;5;0;48;5;15m"
|
||||
)
|
||||
@@ -68,14 +68,14 @@ func printFileEntry(entry string, lastSlash int, charCounter int, colorAlternato
|
||||
}
|
||||
|
||||
// print fileEntryName to screen
|
||||
fmt.Printf("%s%s%s ", colorCode, fileEntryName, ansiReset)
|
||||
fmt.Printf("%s%s%s ", colorCode, fileEntryName, offline.AnsiReset)
|
||||
|
||||
return charCounter, colorAlternator
|
||||
}
|
||||
|
||||
// EntryListGen generates and displays full libmutton entry list
|
||||
func EntryListGen() {
|
||||
fmt.Print("\n" + ansiBlackOnWhite + "libmutton entries:" + ansiReset)
|
||||
fmt.Print("\n" + ansiBlackOnWhite + "libmutton entries:" + offline.AnsiReset)
|
||||
|
||||
// define file/directory containing slices so that they may be accessed by the anonymous WalkDir function
|
||||
var fileList []string
|
||||
@@ -93,7 +93,7 @@ func EntryListGen() {
|
||||
dirList = append(dirList, "")
|
||||
} else {
|
||||
// otherwise, print the source of the error
|
||||
fmt.Print("\n\n\033[38;5;9mAn unexpected error occurred while generating the entry list: " + err.Error() + ansiReset)
|
||||
fmt.Print("\n\n" + offline.AnsiError + "An unexpected error occurred while generating the entry list: " + err.Error() + offline.AnsiReset)
|
||||
}
|
||||
// quit walking EntryRoot and return nil to allow the program to continue
|
||||
return nil
|
||||
@@ -161,9 +161,9 @@ func EntryListGen() {
|
||||
skippedDirList[i] = false // the directory header is being printed, indicate that it is not being skipped
|
||||
indent, vanityDirectory = indentSubtractor(skippedDirList, dirList, i, indent) // calculate the final indentation multiplier
|
||||
if !offline.Windows { // for consistency, format directories with UNIX-style path separators on all platforms
|
||||
fmt.Printf("\n\n"+strings.Repeat(" ", indent*2)+"\033[38;5;7;48;5;8m%s/"+ansiReset+"\n", vanityDirectory)
|
||||
fmt.Printf("\n\n"+strings.Repeat(" ", indent*2)+"\033[38;5;7;48;5;8m%s/"+offline.AnsiReset+"\n", vanityDirectory)
|
||||
} else {
|
||||
fmt.Printf("\n\n"+strings.Repeat(" ", indent*2)+"\033[38;5;7;48;5;8m%s/"+ansiReset+"\n", strings.ReplaceAll(vanityDirectory, offline.PathSeparator, "/"))
|
||||
fmt.Printf("\n\n"+strings.Repeat(" ", indent*2)+"\033[38;5;7;48;5;8m%s/"+offline.AnsiReset+"\n", strings.ReplaceAll(vanityDirectory, offline.PathSeparator, "/"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,11 +177,11 @@ func EntryListGen() {
|
||||
skippedDirList[i] = false // the directory header is being printed, indicate that it is not being skipped
|
||||
indent, vanityDirectory = indentSubtractor(skippedDirList, dirList, i, indent) // calculate the final indentation multiplier
|
||||
if !offline.Windows { // for consistency, format directories with UNIX-style path separators on all platforms
|
||||
fmt.Printf("\n\n"+strings.Repeat(" ", indent*2)+"\033[38;5;7;48;5;8m%s/"+ansiReset+"\n", vanityDirectory)
|
||||
fmt.Printf("\n\n"+strings.Repeat(" ", indent*2)+"\033[38;5;7;48;5;8m%s/"+offline.AnsiReset+"\n", vanityDirectory)
|
||||
} else {
|
||||
fmt.Printf("\n\n"+strings.Repeat(" ", indent*2)+"\033[38;5;7;48;5;8m%s/"+ansiReset+"\n", strings.ReplaceAll(vanityDirectory, offline.PathSeparator, "/"))
|
||||
fmt.Printf("\n\n"+strings.Repeat(" ", indent*2)+"\033[38;5;7;48;5;8m%s/"+offline.AnsiReset+"\n", strings.ReplaceAll(vanityDirectory, offline.PathSeparator, "/"))
|
||||
}
|
||||
fmt.Print(strings.Repeat(" ", indent*2) + "\033[38;5;11m-empty directory-" + ansiReset)
|
||||
fmt.Print(strings.Repeat(" ", indent*2) + "\033[38;5;11m-empty directory-" + offline.AnsiReset)
|
||||
} else { // warn if the only thing that exists is the root-level directory
|
||||
fmt.Print("\n\nNothing's here! For help creating your first entry, run \"mutn help\".")
|
||||
}
|
||||
|
||||
+32
-29
@@ -1,6 +1,9 @@
|
||||
package cli
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/rwinkhart/MUTN/src/offline"
|
||||
)
|
||||
|
||||
// global constants used only in this file
|
||||
const (
|
||||
@@ -9,13 +12,13 @@ const (
|
||||
)
|
||||
|
||||
func HelpMain() {
|
||||
fmt.Print(ansiBold + "\nMUTN | Copyright (c) 2024 Randall Winkhart\n" + ansiReset + `
|
||||
fmt.Print(ansiBold + "\nMUTN | Copyright (c) 2024 Randall Winkhart\n" + offline.AnsiReset + `
|
||||
This software exists under the MIT license; you may redistribute it under certain conditions.
|
||||
This program comes with absolutely no warranty; type "mutn version" for details.
|
||||
|
||||
` + ansiBold + "Usage:" + ansiReset + ` mutn [/<entry name> [argument] [option]] | [argument]
|
||||
` + ansiBold + "Usage:" + offline.AnsiReset + ` mutn [/<entry name> [argument] [option]] | [argument]
|
||||
|
||||
` + ansiBold + "Arguments:" + ansiReset + `
|
||||
` + ansiBold + "Arguments:" + offline.AnsiReset + `
|
||||
help/--help/-h Bring up this menu
|
||||
version/-v Display version and license information
|
||||
init Set up MUTN
|
||||
@@ -27,7 +30,7 @@ This program comes with absolutely no warranty; type "mutn version" for details.
|
||||
shear Delete an existing entry
|
||||
sync Manually sync the entry directory
|
||||
|
||||
` + ansiBold + "Options:" + ansiReset + `
|
||||
` + ansiBold + "Options:" + offline.AnsiReset + `
|
||||
add:
|
||||
password/-p Add a password entry
|
||||
note/-n Add a note entry
|
||||
@@ -46,15 +49,15 @@ This program comes with absolutely no warranty; type "mutn version" for details.
|
||||
gen:
|
||||
update/-u Generate a password for an existing entry
|
||||
|
||||
` + ansiBold + "Tip 1:" + ansiReset + ` You can quickly read an entry with "mutn /<entry name>"
|
||||
` + ansiBold + "Tip 2:" + ansiReset + ` Type "mutn" (no arguments/options) to view a list of saved entries
|
||||
` + ansiBold + "Tip 3:" + ansiReset + " Provide \"add\", \"edit\", \"copy\", or \"gen\" as the only argument to receive more specific help\n\n")
|
||||
` + ansiBold + "Tip 1:" + offline.AnsiReset + ` You can quickly read an entry with "mutn /<entry name>"
|
||||
` + ansiBold + "Tip 2:" + offline.AnsiReset + ` Type "mutn" (no arguments/options) to view a list of saved entries
|
||||
` + ansiBold + "Tip 3:" + offline.AnsiReset + " Provide \"add\", \"edit\", \"copy\", or \"gen\" as the only argument to receive more specific help\n\n")
|
||||
}
|
||||
|
||||
func HelpAdd() {
|
||||
fmt.Print(ansiBold + "\nUsage:" + ansiReset + ` mutn /<entry name> add <option>
|
||||
fmt.Print(ansiBold + "\nUsage:" + offline.AnsiReset + ` mutn /<entry name> add <option>
|
||||
|
||||
` + ansiBold + "Options:" + ansiReset + `
|
||||
` + ansiBold + "Options:" + offline.AnsiReset + `
|
||||
add:
|
||||
password/-p Add a password entry
|
||||
note/-n Add a note entry
|
||||
@@ -62,9 +65,9 @@ func HelpAdd() {
|
||||
}
|
||||
|
||||
func HelpEdit() {
|
||||
fmt.Print(ansiBold + "\nUsage:" + ansiReset + ` mutn /<entry name> edit <option>
|
||||
fmt.Print(ansiBold + "\nUsage:" + offline.AnsiReset + ` mutn /<entry name> edit <option>
|
||||
|
||||
` + ansiBold + "Options:" + ansiReset + `
|
||||
` + ansiBold + "Options:" + offline.AnsiReset + `
|
||||
edit:
|
||||
rename/-r Rename or relocate an entry
|
||||
username/-u Change the username of an entry
|
||||
@@ -74,9 +77,9 @@ func HelpEdit() {
|
||||
}
|
||||
|
||||
func HelpCopy() {
|
||||
fmt.Print(ansiBold + "\nUsage:" + ansiReset + ` mutn /<entry name> copy <option>
|
||||
fmt.Print(ansiBold + "\nUsage:" + offline.AnsiReset + ` mutn /<entry name> copy <option>
|
||||
|
||||
` + ansiBold + "Options:" + ansiReset + `
|
||||
` + ansiBold + "Options:" + offline.AnsiReset + `
|
||||
copy:
|
||||
username/-u Copy the username in an entry to your clipboard
|
||||
password/-p Copy the password in an entry to your clipboard
|
||||
@@ -85,17 +88,17 @@ func HelpCopy() {
|
||||
}
|
||||
|
||||
func HelpGen() {
|
||||
fmt.Print(ansiBold + "\nUsage:" + ansiReset + ` mutn /<entry name> gen [option]
|
||||
fmt.Print(ansiBold + "\nUsage:" + offline.AnsiReset + ` mutn /<entry name> gen [option]
|
||||
|
||||
` + ansiBold + "Options:" + ansiReset + `
|
||||
` + ansiBold + "Options:" + offline.AnsiReset + `
|
||||
gen:
|
||||
update/-u Generate a password for an existing entry
|
||||
|
||||
` + ansiBold + "Tip:" + ansiReset + " If no options are provided, a new password entry is generated\n\n")
|
||||
` + ansiBold + "Tip:" + offline.AnsiReset + " If no options are provided, a new password entry is generated\n\n")
|
||||
}
|
||||
|
||||
func Version() {
|
||||
fmt.Print(ansiBold + "\n MIT License" + ansiReset + `
|
||||
fmt.Print(ansiBold + "\n MIT License" + offline.AnsiReset + `
|
||||
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
@@ -123,18 +126,18 @@ ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
"\n\n---------------------------------------------------------" +
|
||||
"\n\n MUTN is a simple, self-hosted,\n SSH-synchronized password manager based on libmutton\n\n" +
|
||||
" .. ..\n" +
|
||||
" /()\\''.''. " + ansiGoFuchsia + "♥♥♥♥" + ansiReset + " .''.''/()\\ _)\n" +
|
||||
" _. : * " + ansiGoFuchsia + "♥♥♥♥♥♥ ♥♥♥♥♥♥♥♥" + ansiReset + " * : <[◎]|_|=\n" +
|
||||
" }-}-*] `..'..' " + ansiGoFuchsia + "♥♥♥♥♥♥♥♥♥♥♥♥♥" + ansiReset + " `..'..' |\n" +
|
||||
" ◎-◎ // \\\\ " + ansiGoFuchsia + "♥♥♥♥♥♥♥♥♥" + ansiReset + " // \\\\ /|\\\n" +
|
||||
" /()\\''.''. " + ansiGoFuchsia + "♥♥♥♥" + offline.AnsiReset + " .''.''/()\\ _)\n" +
|
||||
" _. : * " + ansiGoFuchsia + "♥♥♥♥♥♥ ♥♥♥♥♥♥♥♥" + offline.AnsiReset + " * : <[◎]|_|=\n" +
|
||||
" }-}-*] `..'..' " + ansiGoFuchsia + "♥♥♥♥♥♥♥♥♥♥♥♥♥" + offline.AnsiReset + " `..'..' |\n" +
|
||||
" ◎-◎ // \\\\ " + ansiGoFuchsia + "♥♥♥♥♥♥♥♥♥" + offline.AnsiReset + " // \\\\ /|\\\n" +
|
||||
ansiGoGopher + "<><><><><><><><><><><><><><>-<><><><><><><><><><><><><><>\n" +
|
||||
"\\" + ansiBlackOnWhite + " " + ansiReset + ansiGoGopher + "/\n" +
|
||||
"\\" + ansiBlackOnWhite + " MUTN Version 0.0.1 " + ansiReset + ansiGoGopher + "/\n" +
|
||||
"\\" + ansiBlackOnWhite + " The Butchered Update " + ansiReset + ansiGoGopher + "/\n" +
|
||||
"\\" + ansiBlackOnWhite + " " + ansiReset + ansiGoGopher + "/\n" +
|
||||
"\\" + ansiBlackOnWhite + " Copyright (c) 2024 Randall Winkhart " + ansiReset + ansiGoGopher + "/\n" +
|
||||
"\\" + ansiBlackOnWhite + " " + ansiReset + ansiGoGopher + "/\n" +
|
||||
"<><><><><><><><><><><><><><>-<><><><><><><><><><><><><><>\n" + ansiReset +
|
||||
"\\" + ansiBlackOnWhite + " " + offline.AnsiReset + ansiGoGopher + "/\n" +
|
||||
"\\" + ansiBlackOnWhite + " MUTN Version 0.0.1 " + offline.AnsiReset + ansiGoGopher + "/\n" +
|
||||
"\\" + ansiBlackOnWhite + " The Butchered Update " + offline.AnsiReset + ansiGoGopher + "/\n" +
|
||||
"\\" + ansiBlackOnWhite + " " + offline.AnsiReset + ansiGoGopher + "/\n" +
|
||||
"\\" + ansiBlackOnWhite + " Copyright (c) 2024 Randall Winkhart " + offline.AnsiReset + ansiGoGopher + "/\n" +
|
||||
"\\" + ansiBlackOnWhite + " " + offline.AnsiReset + ansiGoGopher + "/\n" +
|
||||
"<><><><><><><><><><><><><><>-<><><><><><><><><><><><><><>\n" + offline.AnsiReset +
|
||||
"\n For more information, see:\n\n" +
|
||||
" https://github.com/rwinkhart/MUTN\n" +
|
||||
" https://github.com/rwinkhart/libmutton\n\n")
|
||||
|
||||
@@ -8,3 +8,9 @@ import (
|
||||
var (
|
||||
home, _ = os.UserHomeDir()
|
||||
)
|
||||
|
||||
// global constants used across multiple files
|
||||
const (
|
||||
AnsiError = "\033[38;5;9m"
|
||||
AnsiReset = "\033[0m"
|
||||
)
|
||||
@@ -0,0 +1,57 @@
|
||||
package offline
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gopkg.in/ini.v1"
|
||||
"os"
|
||||
)
|
||||
|
||||
var Config = make(map[string]interface{})
|
||||
|
||||
func ReadConfig() {
|
||||
cfg, err := ini.Load(home + "/.config/libmutton/libmutton.ini")
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "\033[38;5;9mFailed to load libmutton.ini" + AnsiReset)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// OFFLINE
|
||||
Config["gpgID"] = cfg.Section("OFFLINE").Key("gpgID").String()
|
||||
Config["textEditor"] = cfg.Section("OFFLINE").Key("textEditor").String()
|
||||
|
||||
// ONLINE (conditional)
|
||||
onlineMode, err := cfg.Section("OFFLINE").Key("onlineMode").Bool()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "\033[38;5;9mFailed to enable online (synced) mode - [OFFLINE]/onlineMode in libmutton.ini must be a boolean value - continuing in offline mode" + AnsiReset)
|
||||
onlineMode = false
|
||||
}
|
||||
if onlineMode {
|
||||
Config["sshError"], err = cfg.Section("ONLINE").Key("sshError").Bool()
|
||||
if err != nil {
|
||||
cfg.Section("ONLINE").Key("sshError").SetValue("true")
|
||||
}
|
||||
Config["netPinEnabled"], err = cfg.Section("ONLINE").Key("netPinEnabled").Bool()
|
||||
if err != nil {
|
||||
cfg.Section("ONLINE").Key("netPinEnabled").SetValue("false")
|
||||
}
|
||||
Config["remoteUser"] = cfg.Section("ONLINE").Key("remoteUser").String()
|
||||
Config["remoteIP"] = cfg.Section("ONLINE").Key("remoteIP").String()
|
||||
Config["remotePort"], err = cfg.Section("ONLINE").Key("remotePort").Int()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "\033[38;5;9mFailed to enable online (synced) mode - [ONLINE]/remotePort in libmutton.ini must be an integer value- continuing in offline mode" + AnsiReset)
|
||||
// remotePort == 0 represents offline-only mode
|
||||
Config["remotePort"] = 0
|
||||
}
|
||||
Config["identityFile"] = cfg.Section("ONLINE").Key("identityFile").String()
|
||||
} else {
|
||||
// remotePort == 0 represents offline-only mode
|
||||
Config["remotePort"] = 0
|
||||
}
|
||||
|
||||
// DEBUG config
|
||||
//for key, value := range Config {
|
||||
// fmt.Print(key + ": ")
|
||||
// fmt.Println(value)
|
||||
//}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user