Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add OIDC user to the functional test #3235

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 7 additions & 12 deletions lib/pbench/client/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

from pbench.client.oidc_admin import OIDCAdmin
from pbench.client.types import Dataset, JSONOBJECT
from pbench.server.auth import OpenIDClientError


class PbenchClientError(Exception):
Expand Down Expand Up @@ -340,17 +339,13 @@ def login(self, user: str, password: str):
user: Account username
password: Account password
"""
try:
response = self.oidc_admin.user_login(
client_id=self.endpoints["openid"]["client"],
username=user,
password=password,
)
except OpenIDClientError:
self.auth_token = None
else:
self.username = user
self.auth_token = response["access_token"]
response = self.oidc_admin.user_login(
client_id=self.endpoints["openid"]["client"],
username=user,
password=password,
)
self.username = user
self.auth_token = response["access_token"]

def upload(self, tarball: Path, **kwargs) -> requests.Response:
"""Upload a tarball to the server.
Expand Down
5 changes: 1 addition & 4 deletions lib/pbench/client/oidc_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ def create_new_user(
admin_token = self.get_admin_token().get("access_token")
url_path = f"/admin/realms/{self.OIDC_REALM}/users"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {admin_token}",
}
webbnh marked this conversation as resolved.
Show resolved Hide resolved
data = {
Expand Down Expand Up @@ -102,15 +101,14 @@ def user_login(self, client_id: str, username: str, password: str) -> dict:

"""
url_path = f"/realms/{self.OIDC_REALM}/protocol/openid-connect/token"
headers = {"Content-Type": "application/x-www-form-urlencoded"}
data = {
"client_id": client_id,
"grant_type": "password",
"scope": "profile email",
"username": username,
"password": password,
}
return self.post(path=url_path, data=data, headers=headers).json()
return self.post(path=url_path, data=data).json()

def get_user(self, username: str, token: str) -> dict:
"""Get the OIDC user representation dict.
Expand Down Expand Up @@ -138,7 +136,6 @@ def get_user(self, username: str, token: str) -> dict:
response = self.get(
f"admin/realms/{self.OIDC_REALM}/users",
headers={
"Content-Type": "application/json",
"Authorization": f"Bearer {token}",
},
username=username,
dbutenhof marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
32 changes: 16 additions & 16 deletions lib/pbench/server/auth/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from dataclasses import dataclass
from http import HTTPStatus
import logging
from typing import Dict, Optional, Union
from typing import Any, Dict, Optional
webbnh marked this conversation as resolved.
Show resolved Hide resolved
from urllib.parse import urljoin

import jwt
Expand Down Expand Up @@ -38,7 +38,7 @@ class Connection:
def __init__(
self,
server_url: str,
headers: Optional[Dict[str, str]] = None,
headers: Optional[dict[str, str]] = None,
verify: bool = True,
):
self.server_url = server_url
Expand All @@ -50,18 +50,18 @@ def _method(
self,
method: str,
path: str,
data: Union[Dict, str, None],
json: Optional[Dict] = None,
headers: Optional[Dict] = None,
data: Optional[Any] = None,
json: Optional[dict[str, Any]] = None,
headers: Optional[dict[str, str]] = None,
**kwargs,
) -> requests.Response:
"""Common frontend for the HTTP operations on OIDC client connection.

Args:
method : The API HTTP method
path : Path for the request.
data : Data to send with the request in case of the POST
json: JSON data to send with the request in case of the POST
data : Form data to send with the request in case of the POST
json : JSON data to send with the request in case of the POST
kwargs : Additional keyword args

Returns:
Expand All @@ -71,15 +71,15 @@ def _method(
if headers is not None:
final_headers.update(headers)
url = urljoin(self.server_url, path)
kwargs = dict(
request_dict = dict(
params=kwargs,
data=data,
json=json,
headers=final_headers,
verify=self.verify,
)
try:
response = self._connection.request(method, url, **kwargs)
response = self._connection.request(method, url, **request_dict)
except requests.exceptions.ConnectionError as exc:
raise OpenIDClientError(
http_status=HTTPStatus.BAD_GATEWAY,
Expand Down Expand Up @@ -113,7 +113,7 @@ def _method(
return response

def get(
self, path: str, headers: Optional[Dict] = None, **kwargs
self, path: str, headers: Optional[dict[str, str]] = None, **kwargs
) -> requests.Response:
"""GET wrapper to handle an authenticated GET operation on the Resource
at a given path.
Expand All @@ -126,23 +126,23 @@ def get(
Returns:
Response from the request.
"""
return self._method("GET", path, None, None, headers=headers, **kwargs)
return self._method("GET", path, headers=headers, **kwargs)

def post(
self,
path: str,
data: Union[Dict, str] = None,
json: Optional[Dict] = None,
headers: Optional[Dict] = None,
data: Optional[Any] = None,
dbutenhof marked this conversation as resolved.
Show resolved Hide resolved
json: Optional[dict[str, Any]] = None,
headers: Optional[dict[str, str]] = None,
**kwargs,
) -> requests.Response:
"""POST wrapper to handle an authenticated POST operation on the
Resource at a given path.

Args:
path : Path for the request
data : Request body to attach
json: JSON request body
data : Optional HTML form body to attach
json : JSON request body
headers : Additional headers to add to the request
kwargs : Additional keyword args to be added as URL parameters

Expand Down
4 changes: 2 additions & 2 deletions lib/pbench/test/functional/server/test_connect.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,5 @@ def test_connect(self, server_client: PbenchServerClient):

# verify all the required openid-connect fields are present
if "openid" in endpoints:
expected = {"server", "client", "realm"}
assert set(endpoints["openid"]) == expected
expected = {"client", "realm", "server"}
dbutenhof marked this conversation as resolved.
Show resolved Hide resolved
assert set(endpoints["openid"]) >= expected
6 changes: 5 additions & 1 deletion lib/pbench/test/unit/client/test_login.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from http import HTTPStatus

import pytest
import responses

from pbench.server.auth import OpenIDClientError


class TestLogin:
def test_login(self, connect):
Expand Down Expand Up @@ -38,7 +41,8 @@ def test_bad_login(self, connect):
status=HTTPStatus.UNAUTHORIZED,
json={"error_description": "Invalid user credentials"},
)
connect.login("user", "password")
with pytest.raises(OpenIDClientError):
connect.login("user", "password")
assert len(rsp.calls) == 1
assert rsp.calls[0].request.url == url
assert rsp.calls[0].response.status_code == 401
Expand Down
11 changes: 8 additions & 3 deletions lib/pbench/test/unit/server/auth/test_auth.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import configparser
from dataclasses import dataclass
from http import HTTPStatus
from typing import Dict, Optional, Tuple, Union
from typing import Any, Dict, Optional, Tuple, Union

from flask import current_app, Flask
import jwt
Expand Down Expand Up @@ -43,7 +43,12 @@ def fake_method(self, monkeypatch):
args = {}

def fake_method(
the_self, method: str, path: str, data: Dict, json: Dict, **kwargs
the_self,
method: str,
path: str,
data: Optional[Any] = None,
json: Optional[dict[str, Any]] = None,
**kwargs,
) -> requests.Response:
args["method"] = method
args["path"] = path
Expand Down Expand Up @@ -176,7 +181,7 @@ def test_post(self, fake_method, conn):
"""
args = fake_method
response = conn.post(
"foo/bar", {"one": "two", "three": "four"}, None, five="six"
"foo/bar", data={"one": "two", "three": "four"}, five="six"
)
assert response is not None
assert args["method"] == "POST"
Expand Down