mirror of
https://github.com/rwinkhart/MUTN.git
synced 2026-08-28 12:56:30 -04:00
Implement password generation on new entries
This commit is contained in:
@@ -35,7 +35,8 @@ func main() {
|
||||
cli.EntryReaderShortcut(targetLocation, false)
|
||||
case "shear":
|
||||
offline.Shear(targetLocation)
|
||||
case "gen": // TODO offline.Gen(targetLocation), exit after run
|
||||
case "gen":
|
||||
cli.AddEntry(targetLocation, true, 1)
|
||||
case "copy":
|
||||
cli.HelpCopy()
|
||||
case "edit":
|
||||
@@ -87,30 +88,40 @@ func main() {
|
||||
switch args[3] {
|
||||
case "password", "-p":
|
||||
if argsCount == 4 {
|
||||
cli.AddEntry(targetLocation, true, false)
|
||||
cli.AddEntry(targetLocation, true, 0)
|
||||
} else {
|
||||
switch args[4] {
|
||||
case "show", "-s":
|
||||
cli.AddEntry(targetLocation, false, false)
|
||||
cli.AddEntry(targetLocation, false, 0)
|
||||
default:
|
||||
cli.AddEntry(targetLocation, true, false)
|
||||
cli.AddEntry(targetLocation, true, 0)
|
||||
}
|
||||
}
|
||||
case "note", "-n":
|
||||
cli.AddEntry(targetLocation, true, true)
|
||||
cli.AddEntry(targetLocation, true, 2)
|
||||
case "folder", "-f":
|
||||
offline.AddFolder(targetLocation)
|
||||
default:
|
||||
cli.HelpAdd()
|
||||
}
|
||||
case "gen":
|
||||
var field rune
|
||||
field = field // TODO temporary to avoid unused variable error
|
||||
switch args[3] {
|
||||
case "update", "-u": // TODO offline.GenUpdate(targetLocation), exit after run
|
||||
default:
|
||||
cli.HelpGen()
|
||||
if argsCount == 4 {
|
||||
switch args[3] {
|
||||
case "show", "-s":
|
||||
cli.AddEntry(targetLocation, false, 1)
|
||||
case "update", "-u": // TODO offline.GenUpdate(targetLocation), exit after run
|
||||
default:
|
||||
cli.HelpGen()
|
||||
}
|
||||
} else if args[3] == "update" || args[3] == "-u" {
|
||||
switch args[4] {
|
||||
case "show", "-s":
|
||||
cli.AddEntry(targetLocation, false, 1)
|
||||
default:
|
||||
cli.AddEntry(targetLocation, true, 1)
|
||||
}
|
||||
}
|
||||
cli.HelpGen()
|
||||
default:
|
||||
cli.HelpMain()
|
||||
}
|
||||
|
||||
+12
-3
@@ -7,7 +7,8 @@ import (
|
||||
)
|
||||
|
||||
// AddEntry creates a new entry at targetLocation by taking user input via CLI prompts
|
||||
func AddEntry(targetLocation string, hidePassword bool, isNote bool) {
|
||||
// entryType: 0 = standard (password), 1 = auto-generated password, 2 = note
|
||||
func AddEntry(targetLocation string, hidePassword bool, entryType uint8) {
|
||||
_, isAccessible := offline.TargetIsFile(targetLocation, false, 0)
|
||||
if isAccessible {
|
||||
fmt.Println(offline.AnsiError + "Target location already exists" + offline.AnsiReset)
|
||||
@@ -16,9 +17,17 @@ func AddEntry(targetLocation string, hidePassword bool, isNote bool) {
|
||||
|
||||
var unencryptedEntry []string
|
||||
|
||||
if !isNote {
|
||||
if entryType < 2 {
|
||||
username := input("Username:")
|
||||
password := inputHidden("Password:")
|
||||
|
||||
// determine whether to generate the password
|
||||
var password string
|
||||
if entryType == 0 {
|
||||
password = inputHidden("Password:")
|
||||
} else {
|
||||
password = offline.StringGen(inputInt("Password length:"), inputBinary("Generate a complex (special characters) password?"), 0.2)
|
||||
}
|
||||
|
||||
url := input("URL:")
|
||||
if inputBinary("Add a note to this entry?") {
|
||||
note := newNote()
|
||||
|
||||
@@ -12,9 +12,9 @@ import (
|
||||
// input prompts the user for input and returns the input as a string
|
||||
func input(prompt string) string {
|
||||
fmt.Print("\n" + prompt + " ")
|
||||
var input string
|
||||
fmt.Scanln(&input)
|
||||
return input
|
||||
var userInput string
|
||||
fmt.Scanln(&userInput)
|
||||
return userInput
|
||||
}
|
||||
|
||||
// inputHidden prompts the user for input and returns the input as a string, hiding the input from the terminal
|
||||
@@ -26,6 +26,20 @@ func inputHidden(prompt string) string {
|
||||
return password
|
||||
}
|
||||
|
||||
// inputInt prompts the user for input and returns the input as an integer
|
||||
func inputInt(prompt string) int {
|
||||
|
||||
// loop until a valid integer is entered
|
||||
for {
|
||||
fmt.Print("\n" + prompt + " ")
|
||||
var userInput int
|
||||
_, err := fmt.Scanln(&userInput)
|
||||
if err == nil {
|
||||
return userInput
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// inputBinary prompts the user with a yes/no question and returns the response as a boolean
|
||||
func inputBinary(prompt string) bool {
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
package offline
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"math/big"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// TargetIsFile TargetStatusCheck checks if the targetLocation is a file, directory, or is inaccessible
|
||||
@@ -63,3 +67,50 @@ func RemoveTrailingEmptyStrings(slice []string) []string {
|
||||
}
|
||||
return []string{}
|
||||
}
|
||||
|
||||
// StringGen generates a random string of a specified length and complexity
|
||||
// complexity: minimum percentage of special characters to be returned in the generated string (only impacts complex strings)
|
||||
func StringGen(length int, complex bool, complexity float64) string {
|
||||
var extendedCharset string // hold extended character set used for complex strings
|
||||
var actualSpecialChars int // track the number of special characters in the generated string
|
||||
var minSpecialChars int // track the minimum number of special characters to accept
|
||||
|
||||
charset := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" // default character set used for all strings
|
||||
if complex {
|
||||
minSpecialChars = int(math.Round(float64(length) * complexity)) // determine minimum number of special characters to accept
|
||||
extendedCharset = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"
|
||||
charset = charset + extendedCharset
|
||||
} else {
|
||||
extendedCharset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
}
|
||||
|
||||
for {
|
||||
// generate a random string
|
||||
result := make([]byte, length)
|
||||
for i := range result {
|
||||
val, _ := rand.Int(rand.Reader, big.NewInt(int64(len(charset))))
|
||||
result[i] = charset[val.Int64()]
|
||||
}
|
||||
|
||||
// return early if the string is not complex
|
||||
if !complex {
|
||||
return string(result)
|
||||
}
|
||||
|
||||
// count the number of special characters in the generated string
|
||||
for _, char := range string(result) {
|
||||
if strings.ContainsRune(extendedCharset, char) {
|
||||
actualSpecialChars++
|
||||
}
|
||||
}
|
||||
|
||||
// return the generated string if it contains enough special characters
|
||||
if actualSpecialChars >= minSpecialChars {
|
||||
return string(result)
|
||||
}
|
||||
|
||||
// reset special character counter
|
||||
fmt.Println("Regenerating string until desired complexity is achieved...")
|
||||
actualSpecialChars = 0
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user