Skip to content

Commit

Permalink
Change oauth2 client parameters
Browse files Browse the repository at this point in the history
This introduces --client-id and --client-auth. Users can now infer the
authentication to use in face of multiple available security proposals.
  • Loading branch information
mdellweg committed Sep 17, 2024
1 parent c35f529 commit 24b5d00
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 11 deletions.
2 changes: 2 additions & 0 deletions CHANGES/+oauth2_client_credentials.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Changed the way OAuth2 Client Credentials are provided to give the user some choice over the authentication to use.
The new parameters `--client-id` and `--client-secret` were added and `--username`, `--password` are now restricted to HTTP Basic.
8 changes: 6 additions & 2 deletions pulp_cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ def main(
headers: t.List[str],
username: t.Optional[str],
password: t.Optional[str],
client_id: t.Optional[str],
client_secret: t.Optional[str],
cert: t.Optional[str],
key: t.Optional[str],
verify_ssl: bool,
Expand All @@ -206,8 +208,6 @@ def _debug_callback(level: int, x: str) -> None:
api_kwargs = dict(
base_url=base_url,
headers=dict((header.split(":", maxsplit=1) for header in headers)),
username=username,
password=password,
cert=cert,
key=key,
validate_certs=verify_ssl,
Expand All @@ -224,6 +224,10 @@ def _debug_callback(level: int, x: str) -> None:
format=format,
background_tasks=background,
timeout=timeout,
username=username,
password=password,
oauth2_client_id=client_id,
oauth2_client_secret=client_secret,
)


Expand Down
10 changes: 9 additions & 1 deletion pulp_cli/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
"headers",
"username",
"password",
"client_id",
"client_secret",
"cert",
"key",
"verify_ssl",
Expand Down Expand Up @@ -59,6 +61,8 @@
),
click.option("--username", default=None, help=_("Username on pulp server")),
click.option("--password", default=None, help=_("Password on pulp server")),
click.option("--client-id", default=None, help=_("OAuth2 client ID")),
click.option("--client-secret", default=None, help=_("OAuth2 client secret")),
click.option("--cert", default="", help=_("Path to client certificate")),
click.option(
"--key",
Expand Down Expand Up @@ -153,7 +157,11 @@ def validate_config(config: t.Dict[str, t.Any], strict: bool = False) -> None:
if unknown_settings:
errors.append(_("Unknown settings: '{}'.").format("','".join(unknown_settings)))
if strict:
missing_settings = set(SETTINGS) - set(config.keys()) - {"plugins", "username", "password"}
missing_settings = (
set(SETTINGS)
- set(config.keys())
- {"plugins", "username", "password", "client_id", "client_secret"}
)
if missing_settings:
errors.append(_("Missing settings: '{}'.").format("','".join(missing_settings)))
if errors:
Expand Down
25 changes: 17 additions & 8 deletions pulpcore/cli/common/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,15 @@ def __init__(
timeout: int,
format: str,
domain: str = "default",
username: t.Optional[str] = None,
password: t.Optional[str] = None,
oauth2_client_id: t.Optional[str] = None,
oauth2_client_secret: t.Optional[str] = None,
) -> None:
self.username = api_kwargs.pop("username", None)
self.password = api_kwargs.pop("password", None)
self.username = username
self.password = password
self.oauth2_client_id = oauth2_client_id
self.oauth2_client_secret = oauth2_client_secret
if not api_kwargs.get("cert"):
api_kwargs["auth_provider"] = PulpCLIAuthProvider(pulp_ctx=self)
super().__init__(
Expand Down Expand Up @@ -170,6 +176,8 @@ def output_result(self, result: t.Any) -> None:
class SecretStorageBasicAuth(requests.auth.AuthBase):
def __init__(self, pulp_ctx: PulpCLIContext):
self.pulp_ctx = pulp_ctx
assert self.pulp_ctx.username is not None

self.attr: t.Dict[str, str] = {
"service": "pulp-cli",
"base_url": self.pulp_ctx.api.base_url,
Expand Down Expand Up @@ -199,6 +207,7 @@ def response_hook(self, response: requests.Response, **kwargs: t.Any) -> request
return response

def __call__(self, request: requests.PreparedRequest) -> requests.PreparedRequest:
assert self.pulp_ctx.username is not None
with closing(secretstorage.dbus_init()) as connection:
collection = secretstorage.get_default_collection(connection)
item = next(collection.search_items(self.attr), None)
Expand Down Expand Up @@ -236,15 +245,15 @@ def basic_auth(self, scopes: t.List[str]) -> t.Optional[requests.auth.AuthBase]:
def oauth2_client_credentials_auth(
self, flow: t.Any, scopes: t.List[str]
) -> t.Optional[requests.auth.AuthBase]:
if self.pulp_ctx.username is None:
# No username -> No basic auth.
if self.pulp_ctx.oauth2_client_id is None:
# No client_id -> No oauth2 client credentials.
return None
if self.pulp_ctx.password is None:
self.pulp_ctx.password = click.prompt("Password/ClientSecret")
if self.pulp_ctx.oauth2_client_secret is None:
self.pulp_ctx.oauth2_client_secret = click.prompt("Client Secret")

return OAuth2ClientCredentialsAuth(
client_id=self.pulp_ctx.username,
client_secret=self.pulp_ctx.password,
client_id=self.pulp_ctx.oauth2_client_id,
client_secret=self.pulp_ctx.oauth2_client_secret,
token_url=flow["tokenUrl"],
# Try to request all possible scopes.
scopes=flow["scopes"],
Expand Down

0 comments on commit 24b5d00

Please sign in to comment.