Configure everything through cmdline, update README
This commit is contained in:
parent
bc93916c76
commit
59e9ec30ef
2 changed files with 86 additions and 37 deletions
74
README.md
74
README.md
|
@ -1,5 +1,5 @@
|
||||||
# pass2csv
|
# pass2csv
|
||||||
Needs [python-gnupg](https://pypi.python.org/pypi/python-gnupg) and python3.
|
Requires [python-gnupg](https://pypi.python.org/pypi/python-gnupg) and python3.
|
||||||
Run with path to password store as argument:
|
Run with path to password store as argument:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -7,40 +7,65 @@ python3 -m pip install --user python-gnupg
|
||||||
python3 pass2csv.py ~/.password-store
|
python3 pass2csv.py ~/.password-store
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
$ pass2csv --help
|
||||||
|
usage: pass2csv.py [-h] [-a] [-b GPGBINARY] [-x] [-l LOGIN_FIELDS [LOGIN_FIELDS ...]] [-u]
|
||||||
|
[-e EXCLUDE_ROWS [EXCLUDE_ROWS ...]]
|
||||||
|
path
|
||||||
|
|
||||||
|
positional arguments:
|
||||||
|
path path to the password-store folder to export
|
||||||
|
|
||||||
|
optional arguments:
|
||||||
|
-h, --help show this help message and exit
|
||||||
|
-a, --agent ask gpg to use its auth agent
|
||||||
|
-b GPGBINARY, --gpgbinary GPGBINARY
|
||||||
|
path to the gpg binary you wish to use
|
||||||
|
-x, --kpx format the CSV for KeePassXC
|
||||||
|
-l LOGIN_FIELDS [LOGIN_FIELDS ...], --login-fields LOGIN_FIELDS [LOGIN_FIELDS ...]
|
||||||
|
strings to interpret as names of login fields (only used with -x)
|
||||||
|
-u, --get-url match row starting with 'url:' and extract it (only used with -x)
|
||||||
|
-e EXCLUDE_ROWS [EXCLUDE_ROWS ...], --exclude-rows EXCLUDE_ROWS [EXCLUDE_ROWS ...]
|
||||||
|
regexp strings to exclude from the notes field (only used with -x)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Export format
|
||||||
There are two ways to export CSV data:
|
There are two ways to export CSV data:
|
||||||
|
|
||||||
1. The format for the KeePass Generic CSV Importer:
|
1. The format for the KeePass Generic CSV Importer:
|
||||||
|
|
||||||
Group(/),Title,Password,Notes
|
Group(/),Title,Password,Notes
|
||||||
|
|
||||||
Where 'Password' is the first line of the entry in `pass` and 'Notes' are all
|
Where 'Password' is the first line of the entry in `pass` and
|
||||||
subsequent lines. '\\' should not be interpreted as an escape character.
|
'Notes' are all subsequent lines. '\\' should not be interpreted as
|
||||||
|
an escape character.
|
||||||
|
|
||||||
To enable, set `KPX_FORMAT=False` in `pass2csv.py`
|
This is the default mode.
|
||||||
|
|
||||||
2. The format for the KeePassXC Importer:
|
2. The format for the KeePassXC Importer:
|
||||||
|
|
||||||
Group(/),Title,Login,Password,URL,Notes
|
Group(/),Title,Login,Password,URL,Notes
|
||||||
|
|
||||||
Where 'Password' is the first line of the entry in `pass`, 'User' is configured
|
Where 'Password' is the first line of the entry in `pass`, 'User' is
|
||||||
with `LOGIN_FIELDS`, URL is extracted if `GET_URL` is set, and 'Notes' contains
|
configured with `-l`, URL is extracted if `-u` is
|
||||||
any other fields that do not match `EXCLUDE_ROWS`.
|
set, and 'Notes' contains any other fields that do not match
|
||||||
|
`-e`.
|
||||||
|
|
||||||
To enable, set `KPX_FORMAT=True` and configure the variables mentioned above in
|
'User' field is chosen by searching for the first field with a name
|
||||||
`pass2csv.py`.
|
set by `-l`. Once the field is found, the login is set and the field
|
||||||
|
is removed from notes.
|
||||||
|
|
||||||
|
Use `-x` or `--kpx` to enable this mode.
|
||||||
|
|
||||||
'User' field is chosen by searching for the first field with a name in
|
|
||||||
LOGIN_FIELDS. Once the field is found, the login is set and the field is
|
|
||||||
removed from notes.
|
|
||||||
|
|
||||||
### Example KeePassXC Import
|
### Example KeePassXC Import
|
||||||
- Variable definitions (`pass2csv.py`)
|
- Cmd line
|
||||||
|
|
||||||
KPX_FORMAT=True
|
pass2csv ~/.password-store -x -l username login email -u -e '^---$'
|
||||||
|
|
||||||
LOGIN_FIELDS=['username', 'login', 'email']
|
|
||||||
GET_URL=True
|
|
||||||
EXCLUDE_ROWS=['^---$']
|
|
||||||
|
|
||||||
- Password entry (`sites/example`)
|
- Password entry (`sites/example`)
|
||||||
|
|
||||||
|
@ -55,16 +80,15 @@ There are two ways to export CSV data:
|
||||||
|
|
||||||
sites, example, user_name, password123, example.com, "email: user@example.com\nsome_note"
|
sites, example, user_name, password123, example.com, "email: user@example.com\nsome_note"
|
||||||
|
|
||||||
- `user_name` was chosen because `username` was the first filled entry in
|
- `user_name` was chosen because `username` was the first argument to `-l`.
|
||||||
`LOGIN_FIELDS`.
|
- Both logn and URL fields were excluded from the notes field because they
|
||||||
- Both logn and URL fields were excluded from the notes field because they were used
|
were used in another field.
|
||||||
in another field.
|
- `---` Was not included in the notes field because it was matched by `-e`.
|
||||||
- `---` Was not included in the notes field because it was matched in `EXCLUDE_ROWS`.
|
|
||||||
|
|
||||||
### Example KeePass Generic CSV Importer
|
### Example KeePass Generic CSV Importer
|
||||||
- Variable definitions (`pass2csv.py`)
|
- Cmd line
|
||||||
|
|
||||||
KPX_FORMAT=False
|
pass2csv ~/.password-store
|
||||||
|
|
||||||
- Password entry: Same as above
|
- Password entry: Same as above
|
||||||
- Output CSV row (formatted)
|
- Output CSV row (formatted)
|
||||||
|
|
49
pass2csv.py
49
pass2csv.py
|
@ -9,7 +9,7 @@ import gnupg
|
||||||
|
|
||||||
|
|
||||||
class CSVExporter():
|
class CSVExporter():
|
||||||
def __init__(self, kpx_format):
|
def __init__(self, kpx_format, login_fields, get_url, exclude_rows):
|
||||||
logging.basicConfig(level=logging.INFO)
|
logging.basicConfig(level=logging.INFO)
|
||||||
self.logger = logging.getLogger(__name__)
|
self.logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -18,12 +18,14 @@ class CSVExporter():
|
||||||
self.kpx_format = kpx_format
|
self.kpx_format = kpx_format
|
||||||
|
|
||||||
if self.kpx_format:
|
if self.kpx_format:
|
||||||
# A list of possible fields (in order) that could be converted to login fields
|
# A list of possible fields (in order) that could be converted to
|
||||||
self.login_fields = ['login', 'user', 'username', 'email']
|
# login fields
|
||||||
|
self.login_fields = login_fields or []
|
||||||
# Set to True to extract url fields
|
# Set to True to extract url fields
|
||||||
self.get_url = True
|
self.get_url = get_url
|
||||||
# A regular expression list of lines that should be excluded from the notes field
|
# A regular expression list of lines that should be excluded from
|
||||||
self.exclude_rows = ['^---$', '^autotype ?: ?']
|
# the notes field
|
||||||
|
self.exclude_rows = exclude_rows or []
|
||||||
|
|
||||||
self.logger.info("Using KPX format: %s", self.kpx_format)
|
self.logger.info("Using KPX format: %s", self.kpx_format)
|
||||||
|
|
||||||
|
@ -102,8 +104,9 @@ class CSVExporter():
|
||||||
return [group, name, password, notes]
|
return [group, name, password, notes]
|
||||||
|
|
||||||
|
|
||||||
def main(kpx_format, gpgbinary, use_agent, pass_path):
|
def main(gpgbinary, use_agent, pass_path,
|
||||||
exporter = CSVExporter(kpx_format)
|
kpx_format, login_fields, get_url, exclude_rows):
|
||||||
|
exporter = CSVExporter(kpx_format, login_fields, get_url, exclude_rows)
|
||||||
gpg = gnupg.GPG(use_agent=use_agent, gpgbinary=gpgbinary)
|
gpg = gnupg.GPG(use_agent=use_agent, gpgbinary=gpgbinary)
|
||||||
gpg.encoding = 'utf-8'
|
gpg.encoding = 'utf-8'
|
||||||
csv_data = []
|
csv_data = []
|
||||||
|
@ -128,20 +131,20 @@ class OptionsParser(ArgumentParser):
|
||||||
'pass_path',
|
'pass_path',
|
||||||
metavar='path',
|
metavar='path',
|
||||||
type=str,
|
type=str,
|
||||||
help="Path to the PasswordStore folder to use",
|
help="path to the password-store folder to export",
|
||||||
)
|
)
|
||||||
|
|
||||||
self.add_argument(
|
self.add_argument(
|
||||||
'-a', '--agent',
|
'-a', '--agent',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help="Use this option to ask gpg to use it's auth agent",
|
help="ask gpg to use its auth agent",
|
||||||
dest='use_agent',
|
dest='use_agent',
|
||||||
)
|
)
|
||||||
|
|
||||||
self.add_argument(
|
self.add_argument(
|
||||||
'-b', '--gpgbinary',
|
'-b', '--gpgbinary',
|
||||||
type=str,
|
type=str,
|
||||||
help="Path to the gpg binary you wish to use",
|
help="path to the gpg binary you wish to use",
|
||||||
dest='gpgbinary',
|
dest='gpgbinary',
|
||||||
default="gpg"
|
default="gpg"
|
||||||
)
|
)
|
||||||
|
@ -149,10 +152,32 @@ class OptionsParser(ArgumentParser):
|
||||||
self.add_argument(
|
self.add_argument(
|
||||||
'-x', '--kpx',
|
'-x', '--kpx',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help="Use this option to format the CSV for KeePassXC",
|
help="format the CSV for KeePassXC",
|
||||||
dest='kpx_format',
|
dest='kpx_format',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.add_argument(
|
||||||
|
'-l', '--login-fields',
|
||||||
|
action='extend',
|
||||||
|
nargs='+',
|
||||||
|
type=str,
|
||||||
|
help="strings to interpret as names of login fields (only used with -x)"
|
||||||
|
)
|
||||||
|
|
||||||
|
self.add_argument(
|
||||||
|
'-u', '--get-url',
|
||||||
|
action='store_true',
|
||||||
|
help="match row starting with 'url:' and extract it (only used with -x)"
|
||||||
|
)
|
||||||
|
|
||||||
|
self.add_argument(
|
||||||
|
'-e', '--exclude-rows',
|
||||||
|
action='extend',
|
||||||
|
nargs='+',
|
||||||
|
type=str,
|
||||||
|
help="regexps to exclude from the notes field (only used with -x)"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
PARSER = OptionsParser()
|
PARSER = OptionsParser()
|
||||||
|
|
Loading…
Reference in a new issue