Skip to content

Commit

Permalink
Added delete-password command
Browse files Browse the repository at this point in the history
Details:

* Added a 'easy-vault delete-password' command that deletes the password for
  a vault file in the keyring service. Added a corresponding
  'Keyring.delete_password()' method. (issues #33 and #35)

Signed-off-by: Andreas Maier <andreas.r.maier@gmx.de>
  • Loading branch information
andy-maier committed Apr 4, 2021
1 parent 24b384a commit 273c8bd
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 3 deletions.
4 changes: 4 additions & 0 deletions docs/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ Released: not yet

**Enhancements:**

* Added a 'easy-vault delete-password' command that deletes the password for
a vault file in the keyring service. Added a corresponding
'Keyring.delete_password()' method. (issues #33 and #35)

**Cleanup:**

**Known issues:**
Expand Down
37 changes: 37 additions & 0 deletions easy_vault/_keyring.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,43 @@ def set_password(self, filepath, password):
keyring.set_password(
self.keyring_service(), self.keyring_username(filepath), password)

def delete_password(self, filepath):
"""
Delete the password for a vault file in the keyring service.
Parameters:
filepath (:term:`unicode string`):
Path name of the vault file. It will be normalized to identify the
keyring item for the vault file.
Returns:
bool: Indicates whether the password existed.
Raises:
:exc:`KeyringNotAvailable`: No keyring service available.
:exc:`KeyringError`: An error happend in the keyring service.
"""
service = self.keyring_service()
username = self.keyring_username(filepath)
try:
pw = keyring.get_password(service, username)
except NO_KEYRING_EXCEPTION as exc:
raise KeyringNotAvailable(str(exc))
except keyring.errors.KeyringError as exc:
raise KeyringError(str(exc))

if pw is None:
return False

try:
keyring.delete_password(service, username)
except NO_KEYRING_EXCEPTION as exc:
raise KeyringNotAvailable(str(exc))
except keyring.errors.KeyringError as exc:
raise KeyringError(str(exc))
return True

def is_available(self):
"""
Indicate whether the keyring service is available on the local system.
Expand Down
24 changes: 23 additions & 1 deletion easy_vault/cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

from ._common_options import add_options, help_option, quiet_option
from .._version import __version__ as cli_version
from .._keyring import Keyring, KeyringNotAvailable
from .._keyring import Keyring, KeyringNotAvailable, KeyringException
from .._easy_vault import EasyVault, EasyVaultException
from .._password import get_password, set_password

Expand Down Expand Up @@ -203,6 +203,28 @@ def cli_check_keyring(**options):
click.echo("Success! Keyring service is available")


@cli.command('delete-password')
@click.argument('vaultfile', type=str, metavar='VAULTFILE', required=True)
@add_options(quiet_option)
@add_options(help_option)
def cli_delete_password(vaultfile, **options):
"""
Delete the password for a vault file in the keyring service.
"""
verbose = not options['quiet']

kr = Keyring()
try:
existed = kr.delete_password(vaultfile)
except KeyringException as exc:
raise click.ClickException(exc)
if verbose:
if existed:
click.echo("Success! Password in keyring service has been deleted")
else:
click.echo("Success! Password in keyring service does not exist")


def check_exists(vaultfile):
if not os.path.exists(vaultfile):
raise click.ClickException(
Expand Down
17 changes: 15 additions & 2 deletions tests/unittest/test_keyring.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@
@pytest.mark.skipif(
not is_keyring_available(), reason="No keyring service available")
# pylint: disable=redefined-outer-name
def test_keyring_get_set(keyring_filepath):
def test_keyring_get_set_delete(keyring_filepath):
"""
Test function for Keyring.get_password() / set_password()
Test function for Keyring.get_password() / set_password() /
delete_password()
"""
kr = Keyring()
password = 'mypassword'
Expand All @@ -38,13 +39,25 @@ def test_keyring_get_set(keyring_filepath):
act_password = kr.get_password(keyring_filepath)
assert act_password is None

# Test that the password does not exist
existed = kr.delete_password(keyring_filepath)
assert existed is False

# Test that setting a password succeeds
kr.set_password(keyring_filepath, password)

# Test that getting a password succeeds and is as expected
act_password = kr.get_password(keyring_filepath)
assert act_password == password

# Delete the password
existed = kr.delete_password(keyring_filepath)
assert existed is True

# Test that the password does not exist
existed = kr.delete_password(keyring_filepath)
assert existed is False


def test_keyring_available():
"""
Expand Down

0 comments on commit 273c8bd

Please sign in to comment.