Skip to content

Commit

Permalink
Retrieve missing password from dbus secret
Browse files Browse the repository at this point in the history
Use the secretservice library to interface with dbus compatible
password managers.

Fixes pulp#821
  • Loading branch information
mdellweg committed Feb 13, 2024
1 parent f492f56 commit d4b20e6
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGES/821.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added support for the dbus secret service to make use of password managers.
1 change: 1 addition & 0 deletions CHANGES/pulp-glue/821.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added `auth` to `apikwargs` so you can plug in any `requests.auth.AuthBase`.
1 change: 1 addition & 0 deletions lower_bounds_constraints.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ toml==0.10.2
pygments==2.17.2
importlib_metadata==4.8.0
importlib_resources==5.4.0
SecretStorage==3.3.3
49 changes: 48 additions & 1 deletion pulpcore/cli/common/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import json
import re
import typing as t
from contextlib import closing
from functools import lru_cache, wraps

import click
Expand Down Expand Up @@ -38,6 +39,13 @@
PYGMENTS = True
PYGMENTS_STYLE = "solarized-dark"

try:
import secretstorage
except ImportError:
SECRET_STORAGE = False
else:
SECRET_STORAGE = True

translation = get_translation(__package__)
_ = translation.gettext

Expand Down Expand Up @@ -139,11 +147,50 @@ def __init__(self, pulp_ctx: PulpCLIContext) -> None:
super().__init__()
self.pulp_ctx = pulp_ctx

def response_hook(self, response: requests.Response, **kwargs: t.Any) -> requests.Response:
# https://docs.python-requests.org/en/latest/_modules/requests/auth/#HTTPDigestAuth
if 200 <= response.status_code < 300 and not self.password_in_manager:
assert isinstance(self.pulp_ctx.password, str)

with closing(secretstorage.dbus_init()) as connection:
collection = secretstorage.get_default_collection(connection)
collection.create_item(
"Pulp CLI", self.attr, self.pulp_ctx.password.encode(), replace=True
)
if response.status_code == 401 and self.password_in_manager:
with closing(secretstorage.dbus_init()) as connection:
collection = secretstorage.get_default_collection(connection)
item = next(collection.search_items(self.attr), None)
if item:
if click.confirm(_("Remove failed password from password manager?")):
item.delete()
self.pulp_ctx.password = None
return response

def __call__(self, request: requests.PreparedRequest) -> requests.PreparedRequest:
if self.pulp_ctx.username is None:
return request
if self.pulp_ctx.password is None:
self.pulp_ctx.password = click.prompt("Password", hide_input=True)

if SECRET_STORAGE:
self.attr: t.Dict[str, str] = {
"service": "pulp-cli",
"base_url": self.pulp_ctx.api.base_url,
"api_path": self.pulp_ctx.api_path,
"username": self.pulp_ctx.username,
}
with closing(secretstorage.dbus_init()) as connection:
collection = secretstorage.get_default_collection(connection)
item = next(collection.search_items(self.attr), None)
if item:
self.pulp_ctx.password = item.get_secret().decode()
self.password_in_manager = True
else:
self.pulp_ctx.password = str(click.prompt("Password", hide_input=True))
self.password_in_manager = False
request.register_hook("response", self.response_hook) # type: ignore
else:
self.pulp_ctx.password = click.prompt("Password", hide_input=True)
wrapped_auth = requests.auth.HTTPBasicAuth(self.pulp_ctx.username, self.pulp_ctx.password)
return wrapped_auth(request) # type: ignore

Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ dependencies = [
[project.optional-dependencies]
pygments = ["pygments>=2.17.2,<2.18"]
shell = ["click-shell~=2.1"]
password-manager = ["SecretStorage>=3.3.3,<3.3.4"]

[project.urls]
documentation = "https://docs.pulpproject.org/pulp_cli/"
Expand Down
1 change: 1 addition & 0 deletions test_requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ python-gnupg==0.5.2

# No pinning here, because we only switch on optional dependencies here.
pygments
SecretStorage

0 comments on commit d4b20e6

Please sign in to comment.