Skip to content

Commit e9fa68c

Browse files
Moved the common fixtures to the root conftest.py or auth_permissions_util.py (feast-dev#54)
* Moved the common fixtures to the root conftest.py or auth_permissions_util.py Signed-off-by: Lokesh Rangineni <lokeshforjava@gmail.com> Signed-off-by: Lokesh Rangineni <lokeshforjava@gmail.com> * Adding missed dependency and regenerated the requirements files. Signed-off-by: Lokesh Rangineni <lokeshforjava@gmail.com> Signed-off-by: Lokesh Rangineni <lokeshforjava@gmail.com> * Addinig missing changes from the original PR. Signed-off-by: Lokesh Rangineni <lokeshforjava@gmail.com> Signed-off-by: Lokesh Rangineni <lokeshforjava@gmail.com> --------- Signed-off-by: Lokesh Rangineni <lokeshforjava@gmail.com>
1 parent 8113ee2 commit e9fa68c

13 files changed

Lines changed: 365 additions & 155 deletions

File tree

sdk/python/feast/permissions/auth/oidc_token_parser.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,11 @@ async def user_details_from_access_token(self, access_token: str) -> User:
7373
signing_key.key,
7474
algorithms=["RS256"],
7575
audience="account",
76-
options={"verify_exp": True},
76+
options={
77+
"verify_aud": False,
78+
"verify_signature": True,
79+
"verify_exp": True,
80+
},
7781
)
7882

7983
if "preferred_username" not in data:
@@ -99,4 +103,5 @@ async def user_details_from_access_token(self, access_token: str) -> User:
99103
logger.info(f"Extracted user {current_user} and roles {roles}")
100104
return User(username=current_user, roles=roles)
101105
except jwt.exceptions.InvalidTokenError:
106+
logger.exception("Exception while parsing the token:")
102107
raise AuthenticationError("Invalid token.")

sdk/python/feast/permissions/client/http_auth_requests_wrapper.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@
1111
class AuthenticatedRequestsSession(Session):
1212
def __init__(self, auth_token: str):
1313
super().__init__()
14-
self.auth_token = auth_token
15-
self.headers.update({"Authorization": f"Bearer {self.auth_token}"})
14+
self.headers.update({"Authorization": f"Bearer {auth_token}"})
1615

1716

1817
def get_http_auth_requests_session(auth_config: AuthConfig) -> Session:

sdk/python/feast/permissions/client/oidc_authentication_client_manager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,5 @@ def get_token(self):
5454
return access_token
5555
else:
5656
raise RuntimeError(
57-
"Failed to obtain access token: {token_response.status_code} - {token_response.text}"
57+
f"""Failed to obtain oidc access token:url=[{token_endpoint}] {token_response.status_code} - {token_response.text}"""
5858
)

sdk/python/requirements/py3.10-ci-requirements.txt

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ async-timeout==4.0.3
4040
# via
4141
# aiohttp
4242
# redis
43+
async-property==0.2.2
44+
# via python-keycloak
4345
atpublic==4.1.0
4446
# via ibis-framework
4547
attrs==23.2.0
@@ -63,6 +65,8 @@ beautifulsoup4==4.12.3
6365
# via nbconvert
6466
bidict==0.23.1
6567
# via ibis-framework
68+
bigtree==0.19.2
69+
# via feast (setup.py)
6670
bleach==6.1.0
6771
# via nbconvert
6872
boto3==1.34.131
@@ -133,6 +137,7 @@ cryptography==42.0.8
133137
# azure-identity
134138
# azure-storage-blob
135139
# great-expectations
140+
# jwcrypto
136141
# moto
137142
# msal
138143
# pyjwt
@@ -156,6 +161,8 @@ defusedxml==0.7.1
156161
# via nbconvert
157162
deltalake==0.18.1
158163
# via feast (setup.py)
164+
deprecation==2.1.0
165+
# via python-keycloak
159166
dill==0.3.8
160167
# via feast (setup.py)
161168
distlib==0.3.8
@@ -323,6 +330,7 @@ httpx==0.27.0
323330
# feast (setup.py)
324331
# fastapi
325332
# jupyterlab
333+
# python-keycloak
326334
ibis-framework[duckdb]==9.1.0
327335
# via
328336
# feast (setup.py)
@@ -432,6 +440,8 @@ jupyterlab-server==2.27.2
432440
# notebook
433441
jupyterlab-widgets==3.0.11
434442
# via ipywidgets
443+
jwcrypto==1.5.6
444+
# via python-keycloak
435445
kubernetes==20.13.0
436446
# via feast (setup.py)
437447
locket==1.0.0
@@ -527,6 +537,7 @@ packaging==24.1
527537
# build
528538
# dask
529539
# db-dtypes
540+
# deprecation
530541
# google-cloud-bigquery
531542
# great-expectations
532543
# gunicorn
@@ -739,6 +750,8 @@ python-dotenv==1.0.1
739750
# via uvicorn
740751
python-json-logger==2.0.7
741752
# via jupyter-events
753+
python-keycloak==4.2.2
754+
# via feast (setup.py)
742755
python-multipart==0.0.9
743756
# via fastapi
744757
pytz==2024.1
@@ -788,14 +801,18 @@ requests==2.32.3
788801
# kubernetes
789802
# moto
790803
# msal
804+
# python-keycloak
791805
# requests-oauthlib
806+
# requests-toolbelt
792807
# responses
793808
# singlestoredb
794809
# snowflake-connector-python
795810
# sphinx
796811
# trino
797812
requests-oauthlib==2.0.0
798813
# via kubernetes
814+
requests-toolbelt==1.0.0
815+
# via python-keycloak
799816
responses==0.25.3
800817
# via moto
801818
rfc3339-validator==0.1.4
@@ -1000,6 +1017,7 @@ typing-extensions==4.12.2
10001017
# great-expectations
10011018
# ibis-framework
10021019
# ipython
1020+
# jwcrypto
10031021
# mypy
10041022
# psycopg
10051023
# psycopg-pool
@@ -1080,4 +1098,3 @@ yarl==1.9.4
10801098
# via aiohttp
10811099
zipp==3.19.1
10821100
# via importlib-metadata
1083-
bigtree==0.19.2

sdk/python/requirements/py3.11-ci-requirements.txt

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ asttokens==2.4.1
3636
# via stack-data
3737
async-lru==2.0.4
3838
# via jupyterlab
39+
async-property==0.2.2
40+
# via python-keycloak
3941
atpublic==4.1.0
4042
# via ibis-framework
4143
attrs==23.2.0
@@ -59,6 +61,8 @@ beautifulsoup4==4.12.3
5961
# via nbconvert
6062
bidict==0.23.1
6163
# via ibis-framework
64+
bigtree==0.19.2
65+
# via feast (setup.py)
6266
bleach==6.1.0
6367
# via nbconvert
6468
boto3==1.34.131
@@ -129,6 +133,7 @@ cryptography==42.0.8
129133
# azure-identity
130134
# azure-storage-blob
131135
# great-expectations
136+
# jwcrypto
132137
# moto
133138
# msal
134139
# pyjwt
@@ -152,6 +157,8 @@ defusedxml==0.7.1
152157
# via nbconvert
153158
deltalake==0.18.1
154159
# via feast (setup.py)
160+
deprecation==2.1.0
161+
# via python-keycloak
155162
dill==0.3.8
156163
# via feast (setup.py)
157164
distlib==0.3.8
@@ -314,6 +321,7 @@ httpx==0.27.0
314321
# feast (setup.py)
315322
# fastapi
316323
# jupyterlab
324+
# python-keycloak
317325
ibis-framework[duckdb]==9.1.0
318326
# via
319327
# feast (setup.py)
@@ -423,6 +431,8 @@ jupyterlab-server==2.27.2
423431
# notebook
424432
jupyterlab-widgets==3.0.11
425433
# via ipywidgets
434+
jwcrypto==1.5.6
435+
# via python-keycloak
426436
kubernetes==20.13.0
427437
# via feast (setup.py)
428438
locket==1.0.0
@@ -518,6 +528,7 @@ packaging==24.1
518528
# build
519529
# dask
520530
# db-dtypes
531+
# deprecation
521532
# google-cloud-bigquery
522533
# great-expectations
523534
# gunicorn
@@ -730,6 +741,8 @@ python-dotenv==1.0.1
730741
# via uvicorn
731742
python-json-logger==2.0.7
732743
# via jupyter-events
744+
python-keycloak==4.2.2
745+
# via feast (setup.py)
733746
python-multipart==0.0.9
734747
# via fastapi
735748
pytz==2024.1
@@ -779,14 +792,18 @@ requests==2.32.3
779792
# kubernetes
780793
# moto
781794
# msal
795+
# python-keycloak
782796
# requests-oauthlib
797+
# requests-toolbelt
783798
# responses
784799
# singlestoredb
785800
# snowflake-connector-python
786801
# sphinx
787802
# trino
788803
requests-oauthlib==2.0.0
789804
# via kubernetes
805+
requests-toolbelt==1.0.0
806+
# via python-keycloak
790807
responses==0.25.3
791808
# via moto
792809
rfc3339-validator==0.1.4
@@ -979,6 +996,7 @@ typing-extensions==4.12.2
979996
# great-expectations
980997
# ibis-framework
981998
# ipython
999+
# jwcrypto
9821000
# mypy
9831001
# psycopg
9841002
# psycopg-pool
@@ -1058,4 +1076,3 @@ yarl==1.9.4
10581076
# via aiohttp
10591077
zipp==3.19.1
10601078
# via importlib-metadata
1061-
bigtree==0.19.2

sdk/python/requirements/py3.9-ci-requirements.txt

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ async-timeout==4.0.3
4040
# via
4141
# aiohttp
4242
# redis
43+
async-property==0.2.2
44+
# via python-keycloak
4345
atpublic==4.1.0
4446
# via ibis-framework
4547
attrs==23.2.0
@@ -63,6 +65,8 @@ beautifulsoup4==4.12.3
6365
# via nbconvert
6466
bidict==0.23.1
6567
# via ibis-framework
68+
bigtree==0.19.2
69+
# via feast (setup.py)
6670
bleach==6.1.0
6771
# via nbconvert
6872
boto3==1.34.131
@@ -133,6 +137,7 @@ cryptography==42.0.8
133137
# azure-identity
134138
# azure-storage-blob
135139
# great-expectations
140+
# jwcrypto
136141
# moto
137142
# msal
138143
# pyjwt
@@ -156,6 +161,8 @@ defusedxml==0.7.1
156161
# via nbconvert
157162
deltalake==0.18.1
158163
# via feast (setup.py)
164+
deprecation==2.1.0
165+
# via python-keycloak
159166
dill==0.3.8
160167
# via feast (setup.py)
161168
distlib==0.3.8
@@ -323,6 +330,7 @@ httpx==0.27.0
323330
# feast (setup.py)
324331
# fastapi
325332
# jupyterlab
333+
# python-keycloak
326334
ibis-framework[duckdb]==9.0.0
327335
# via
328336
# feast (setup.py)
@@ -441,6 +449,8 @@ jupyterlab-server==2.27.2
441449
# notebook
442450
jupyterlab-widgets==3.0.11
443451
# via ipywidgets
452+
jwcrypto==1.5.6
453+
# via python-keycloak
444454
kubernetes==20.13.0
445455
# via feast (setup.py)
446456
locket==1.0.0
@@ -536,6 +546,7 @@ packaging==24.1
536546
# build
537547
# dask
538548
# db-dtypes
549+
# deprecation
539550
# google-cloud-bigquery
540551
# great-expectations
541552
# gunicorn
@@ -748,6 +759,8 @@ python-dotenv==1.0.1
748759
# via uvicorn
749760
python-json-logger==2.0.7
750761
# via jupyter-events
762+
python-keycloak==4.2.2
763+
# via feast (setup.py)
751764
python-multipart==0.0.9
752765
# via fastapi
753766
pytz==2024.1
@@ -797,14 +810,18 @@ requests==2.32.3
797810
# kubernetes
798811
# moto
799812
# msal
813+
# python-keycloak
800814
# requests-oauthlib
815+
# requests-toolbelt
801816
# responses
802817
# singlestoredb
803818
# snowflake-connector-python
804819
# sphinx
805820
# trino
806821
requests-oauthlib==2.0.0
807822
# via kubernetes
823+
requests-toolbelt==1.0.0
824+
# via python-keycloak
808825
responses==0.25.3
809826
# via moto
810827
rfc3339-validator==0.1.4
@@ -1012,6 +1029,7 @@ typing-extensions==4.12.2
10121029
# great-expectations
10131030
# ibis-framework
10141031
# ipython
1032+
# jwcrypto
10151033
# mypy
10161034
# psycopg
10171035
# psycopg-pool
@@ -1094,4 +1112,3 @@ yarl==1.9.4
10941112
# via aiohttp
10951113
zipp==3.19.1
10961114
# via importlib-metadata
1097-
bigtree==0.19.2

sdk/python/tests/conftest.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import multiprocessing
1616
import os
1717
import random
18+
import tempfile
1819
from datetime import timedelta
1920
from multiprocessing import Process
2021
from sys import platform
@@ -24,6 +25,7 @@
2425
import pandas as pd
2526
import pytest
2627
from _pytest.nodes import Item
28+
from testcontainers.keycloak import KeycloakContainer
2729

2830
from feast.data_source import DataSource
2931
from feast.feature_store import FeatureStore # noqa: E402
@@ -54,6 +56,10 @@
5456
driver,
5557
location,
5658
)
59+
from tests.utils.auth_permissions_util import (
60+
default_store,
61+
setup_permissions_on_keycloak,
62+
)
5763
from tests.utils.http_server import check_port_open, free_port # noqa: E402
5864

5965
logger = logging.getLogger(__name__)
@@ -406,3 +412,28 @@ def fake_document_data(environment: Environment) -> Tuple[pd.DataFrame, DataSour
406412
environment.feature_store.project,
407413
)
408414
return df, data_source
415+
416+
417+
@pytest.fixture
418+
def temp_dir():
419+
with tempfile.TemporaryDirectory() as temp_dir:
420+
print(f"Created {temp_dir}")
421+
yield temp_dir
422+
423+
424+
@pytest.fixture
425+
def start_keycloak_server():
426+
with KeycloakContainer("quay.io/keycloak/keycloak:24.0.1") as keycloak_container:
427+
setup_permissions_on_keycloak(keycloak_container.get_client())
428+
yield keycloak_container.get_url()
429+
430+
431+
@pytest.fixture
432+
def server_port():
433+
return free_port()
434+
435+
436+
@pytest.fixture
437+
def feature_store(temp_dir, auth_config, applied_permissions):
438+
print(f"Creating store at {temp_dir}")
439+
return default_store(str(temp_dir), auth_config, applied_permissions)

0 commit comments

Comments
 (0)