aboutsummaryrefslogtreecommitdiff
path: root/yoshi/cli.py
blob: 2e9ce49d5210dcb1a6eb59fe599b78776f542e57 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
"""
This script uses argparse to parse command line arguments.

It imports the required modules and sets up a parser with basic options for demonstration purposes.
"""

import argparse
from yoshi import crypto, database, process


def yoshi():
    """
    CLI entry point logic, used to parse user inputs.
    """
    parser = argparse.ArgumentParser(
        description="Manage your username and passwords via a convenient CLI vault."
    )

    # Top-level arguments
    group_one = parser.add_mutually_exclusive_group()
    group_one.add_argument(
        "-n", "--new", help="Create a new account.", action="store_true"
    )
    group_one.add_argument(
        "-l", "--list", help="List all saved accounts.", action="store_true"
    )
    group_one.add_argument(
        "-e", "--edit", help="Edit a saved account.", action="store_true"
    )
    group_one.add_argument(
        "-d", "--delete", help="Delete a saved account.", action="store_true"
    )
    group_one.add_argument(
        "--purge",
        help=(
            "Purge all accounts and delete the vault. "
            "(Caution: this will irreversibly destroy your data.)"
        ),
        action="store_true",
    )
    group_one.add_argument("--encrypt", help="Encrypt the vault.", action="store_true")
    group_one.add_argument("--decrypt", help="Decrypt the vault.", action="store_true")

    # Encryption flags
    group_two = parser.add_mutually_exclusive_group()
    group_two.add_argument(
        "-g",
        "--generate",
        help=("When using the --encrypt option, generate a new encryption key."),
        action="store_true",
    )
    group_two.add_argument(
        "-k",
        "--keyfile",
        help="Path to existing key file.",
        action="store",
        nargs=1,
        type=str,
    )

    # Edit flags
    group_three = parser.add_argument_group()
    group_three.add_argument(
        "-u",
        "--uuid",
        help=("When using the --edit or --delete options, provide the account UUID."),
        action="store",
        nargs=1,
        type=str,
    )
    group_three.add_argument(
        "-f",
        "--field",
        help=(
            "When using the --edit option, specify the field to edit (integer index)."
        ),
        action="store",
        nargs=1,
        type=int,
    )

    args = parser.parse_args()

    if args.decrypt:
        if args.keyfile:
            key = crypto.load_key(args.keyfile[0])
        else:
            key = input("Please enter your decryption key: ")
        crypto.decrypt(key)
    elif args.encrypt:
        if args.generate:
            key = crypto.generate_key()
            print(
                "WRITE THIS KEY DOWN SOMEWHERE SAFE. YOU WILL NOT BE ABLE TO DECRYPT "
                "YOUR DATA WITHOUT IT!"
            )
            print(key.decode())
            print("\n")
        else:
            if args.keyfile:
                key = crypto.load_key(args.keyfile[0])
            else:
                key = input("Please enter your encryption key: ")
        crypto.encrypt(key)
    elif database.check_table():
        if args.new:
            process.create_account()
        elif args.list:
            process.list_accounts()
        elif args.edit:
            process.edit_account(args.uuid[0], args.field[0])
        elif args.delete:
            process.delete_account(args.uuid[0])
        elif args.purge:
            process.purge_accounts()
        else:
            raise TypeError(
                "Please specify a command or use the --help flag for more information."
            )


if __name__ == "__main__":
    yoshi()