Building a Password Manager in Go: Part 2

Barbara Streisand
Release: 2024-09-25 06:19:02
Original
737 people have browsed it

Welcome back to our journey of building a password manager in Go! In this second installment, we'll explore the progress we've made since our initial commit. We've added new features, improved the code structure, and implemented testing. Let's dive in!

Evolving the Project Structure

One of the first changes you'll notice is the improved project structure. We've separated our code into multiple files and packages, following Go's best practices:

dost/
.
├── LICENSE
├── README.md
├── go.mod
├── go.sum
├── internal
│   ├── internal_test.go
│   └── passgen.go
└── main.go
Copy after login

This structure allows for better organization and maintainability as our project grows.

Enhanced Command-Line Interface

We've significantly improved our CLI, making it more flexible and user-friendly. Here's a snippet from our main.go:

func main() {
    generateCmd := flag.NewFlagSet("generate", flag.ExitOnError)
    flag.Parse()

    switch os.Args[1] {
    case "generate":
        internal.Generate(generateCmd)
    }
}
Copy after login

This setup allows for subcommands, currently supporting the generate command. Users can now interact with our tool like this:

go run main.go generate email/reachme@example.com 15
Copy after login

Customizable Password Generation

We've added options to customize password generation. Users can now specify password length and choose to exclude special characters:

func Generate(generateFlags *flag.FlagSet) {
    generateFlags.BoolVar(&noSymbols, "n", false, "Skip symbols while generating password")
    generateFlags.BoolVar(&copyToClipBoard, "c", false, "Copy to clipboard.")
    generateFlags.Parse(os.Args[2:])
    passwordLength := 25
    // ... (code to parse custom length)

    password, err := generatePassword(passwordLength, noSymbols)
    // ... (code to handle password output)
}
Copy after login

This function allows users to use flags like -n to exclude symbols and -c to copy the password to clipboard instead of displaying it.

Improved Password Generation Algorithm

We've refined our password generation function to handle the new customization options:

func generatePassword(length int, noSymbols bool) (string, error) {
    const (
        uppercaseLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        lowercaseLetters = "abcdefghijklmnopqrstuvwxyz"
        digits           = "0123456789"
        specialChars     = "!@#$%^&*()-_=+[]{}|;:'\",.<>/?"
    )

    allChars := uppercaseLetters + lowercaseLetters + digits
    if !noSymbols {
        allChars += specialChars
    }

    var password string
    for i := 0; i < length; i++ {
    // Generate a random index to select a character from allChars
    randomIndex, err := rand.Int(rand.Reader, big.NewInt(int64(len(allChars))))
    if err != nil {
        return "", err
    }

    // Append the randomly selected character to the password
    password += string(allChars[randomIndex.Int64()])
    }

    return password, nil
}
Copy after login

This function now respects the noSymbols flag, allowing for more flexible password generation.

Implementing Tests

We've taken a significant step towards ensuring the reliability of our code by implementing tests. Here's a snippet from our test file:

func TestPasswordLength(t *testing.T) {
    password, err := generatePassword(10, true)
    if err != nil {
        t.Errorf("Expected no error, got %v", err)
    } else {
        if len(password) != 10 {
            t.Errorf("Expected 10 character password, got %d", len(password))
        }
    }
}

func TestSpecialCharacter10K(t *testing.T) {
    splCharMissing := 0
    for i := 1; i <= 10000; i++ {
        password, err := generatePassword(10, false)
        // ... (code to check for special characters)
    }
    if splCharMissing > 0 {
        t.Errorf("Special character was missing in %d / 10000 instances.", splCharMissing)
    }
}
Copy after login

These tests check for correct password length and the inclusion of special characters. Interestingly, our special character test revealed an area for improvement: in 10,000 generated passwords, 234 didn't contain special characters. This gives us a clear direction for our next refinement.

What's Next?

While we've made significant progress, there's still room for improvement:

  1. Refine the password generation algorithm to ensure consistent inclusion of special characters.
  2. Implement password storage functionality.
  3. Add encryption for stored passwords.
  4. Develop search and retrieval features.

Stay tuned for the next part of our series, where we'll tackle these challenges and continue to evolve our password manager!

Remember, the full source code is available on GitHub. Feel free to clone, fork, and contribute to the project. Your feedback and contributions are always welcome!

Happy coding, and stay secure! ??

Building a Password Manager in Go: Part 2 svemaraju / dost

dost command line password manager written in Go

dost

dost is a CLI password manager written in Go.

Inspired by (Pass)[https://www.passwordstore.org/]

Features

  • Generate random passwords of configurable length
  • Copy generated passwords to clipboard automatically
  • Skip using symbols

Usage

> go build -o dost main.go
Copy after login
Enter fullscreen mode Exit fullscreen mode

Generating password:

> ./dost generate email/vema@example.com
Generated Password: );XE,7-Dv?)Aa+&<{V-|pKuq5
Copy after login

Generating password with specified length (default is 25):

> ./dost generate email/vema@example.com 12
Generated Password: si<yJ=5/lEb3
Copy after login

Copy generated password to clipboard without printing:

> ./dost generate -c email/vema@example.com 
Copied to clipboard! ✅
Copy after login

Avoid symbols for generating passwords:

> ./dost generate -n email/vema@example.com 
Generated Password: E2UST}^{Ac[Fb&D|cD%;Eij>H
Copy after login

Under development

  • Insert a new password manually
  • Show an existing password
  • List all entries
  • Password storage
  • GPG Key based encryption

License

MIT




View on GitHub


The above is the detailed content of Building a Password Manager in Go: Part 2. For more information, please follow other related articles on the PHP Chinese website!

source:dev.to
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!