Skip to content

Commit 2fd82a4

Browse files
lokeshrangineniredhatHameed
authored andcommitted
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 acbe6a6 commit 2fd82a4

13 files changed

Lines changed: 369 additions & 152 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: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ async-timeout==4.0.3
3636
# via
3737
# aiohttp
3838
# redis
39+
async-property==0.2.2
40+
# via python-keycloak
3941
atpublic==4.1.0
4042
# via ibis-framework
4143
attrs==23.2.0
@@ -57,6 +59,8 @@ beautifulsoup4==4.12.3
5759
# via nbconvert
5860
bidict==0.23.1
5961
# via ibis-framework
62+
bigtree==0.19.2
63+
# via feast (setup.py)
6064
bleach==6.1.0
6165
# via nbconvert
6266
boto3==1.34.131
@@ -117,6 +121,7 @@ cryptography==42.0.8
117121
# azure-identity
118122
# azure-storage-blob
119123
# great-expectations
124+
# jwcrypto
120125
# moto
121126
# msal
122127
# pyjwt
@@ -137,6 +142,9 @@ decorator==5.1.1
137142
defusedxml==0.7.1
138143
# via nbconvert
139144
deltalake==0.18.1
145+
# via feast (setup.py)
146+
deprecation==2.1.0
147+
# via python-keycloak
140148
dill==0.3.8
141149
distlib==0.3.8
142150
# via virtualenv
@@ -262,6 +270,7 @@ httpx==0.27.0
262270
# via
263271
# fastapi
264272
# jupyterlab
273+
# python-keycloak
265274
ibis-framework[duckdb]==9.1.0
266275
# via ibis-substrait
267276
ibis-substrait==4.0.0
@@ -366,6 +375,8 @@ jupyterlab-server==2.27.2
366375
# notebook
367376
jupyterlab-widgets==3.0.11
368377
# via ipywidgets
378+
jwcrypto==1.5.6
379+
# via python-keycloak
369380
kubernetes==20.13.0
370381
locket==1.0.0
371382
# via partd
@@ -450,6 +461,7 @@ packaging==24.1
450461
# build
451462
# dask
452463
# db-dtypes
464+
# deprecation
453465
# google-cloud-bigquery
454466
# great-expectations
455467
# gunicorn
@@ -633,6 +645,8 @@ python-dotenv==1.0.1
633645
# via uvicorn
634646
python-json-logger==2.0.7
635647
# via jupyter-events
648+
python-keycloak==4.2.2
649+
# via feast (setup.py)
636650
python-multipart==0.0.9
637651
# via fastapi
638652
pytz==2024.1
@@ -676,14 +690,18 @@ requests==2.32.3
676690
# kubernetes
677691
# moto
678692
# msal
693+
# python-keycloak
679694
# requests-oauthlib
695+
# requests-toolbelt
680696
# responses
681697
# singlestoredb
682698
# snowflake-connector-python
683699
# sphinx
684700
# trino
685701
requests-oauthlib==2.0.0
686702
# via kubernetes
703+
requests-toolbelt==1.0.0
704+
# via python-keycloak
687705
responses==0.25.3
688706
# via moto
689707
rfc3339-validator==0.1.4
@@ -861,6 +879,7 @@ typing-extensions==4.12.2
861879
# great-expectations
862880
# ibis-framework
863881
# ipython
882+
# jwcrypto
864883
# mypy
865884
# psycopg
866885
# psycopg-pool

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ asttokens==2.4.1
3232
# via stack-data
3333
async-lru==2.0.4
3434
# via jupyterlab
35+
async-property==0.2.2
36+
# via python-keycloak
3537
atpublic==4.1.0
3638
# via ibis-framework
3739
attrs==23.2.0
@@ -53,6 +55,8 @@ beautifulsoup4==4.12.3
5355
# via nbconvert
5456
bidict==0.23.1
5557
# via ibis-framework
58+
bigtree==0.19.2
59+
# via feast (setup.py)
5660
bleach==6.1.0
5761
# via nbconvert
5862
boto3==1.34.131
@@ -113,6 +117,7 @@ cryptography==42.0.8
113117
# azure-identity
114118
# azure-storage-blob
115119
# great-expectations
120+
# jwcrypto
116121
# moto
117122
# msal
118123
# pyjwt
@@ -133,6 +138,9 @@ decorator==5.1.1
133138
defusedxml==0.7.1
134139
# via nbconvert
135140
deltalake==0.18.1
141+
# via feast (setup.py)
142+
deprecation==2.1.0
143+
# via python-keycloak
136144
dill==0.3.8
137145
distlib==0.3.8
138146
# via virtualenv
@@ -253,6 +261,7 @@ httpx==0.27.0
253261
# via
254262
# fastapi
255263
# jupyterlab
264+
# python-keycloak
256265
ibis-framework[duckdb]==9.1.0
257266
# via ibis-substrait
258267
ibis-substrait==4.0.0
@@ -357,6 +366,8 @@ jupyterlab-server==2.27.2
357366
# notebook
358367
jupyterlab-widgets==3.0.11
359368
# via ipywidgets
369+
jwcrypto==1.5.6
370+
# via python-keycloak
360371
kubernetes==20.13.0
361372
locket==1.0.0
362373
# via partd
@@ -441,6 +452,7 @@ packaging==24.1
441452
# build
442453
# dask
443454
# db-dtypes
455+
# deprecation
444456
# google-cloud-bigquery
445457
# great-expectations
446458
# gunicorn
@@ -624,6 +636,8 @@ python-dotenv==1.0.1
624636
# via uvicorn
625637
python-json-logger==2.0.7
626638
# via jupyter-events
639+
python-keycloak==4.2.2
640+
# via feast (setup.py)
627641
python-multipart==0.0.9
628642
# via fastapi
629643
pytz==2024.1
@@ -667,14 +681,18 @@ requests==2.32.3
667681
# kubernetes
668682
# moto
669683
# msal
684+
# python-keycloak
670685
# requests-oauthlib
686+
# requests-toolbelt
671687
# responses
672688
# singlestoredb
673689
# snowflake-connector-python
674690
# sphinx
675691
# trino
676692
requests-oauthlib==2.0.0
677693
# via kubernetes
694+
requests-toolbelt==1.0.0
695+
# via python-keycloak
678696
responses==0.25.3
679697
# via moto
680698
rfc3339-validator==0.1.4
@@ -840,6 +858,7 @@ typing-extensions==4.12.2
840858
# great-expectations
841859
# ibis-framework
842860
# ipython
861+
# jwcrypto
843862
# mypy
844863
# psycopg
845864
# psycopg-pool
@@ -912,4 +931,3 @@ yarl==1.9.4
912931
# via aiohttp
913932
zipp==3.19.1
914933
# via importlib-metadata
915-
bigtree==0.19.2

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ async-timeout==4.0.3
3636
# via
3737
# aiohttp
3838
# redis
39+
async-property==0.2.2
40+
# via python-keycloak
3941
atpublic==4.1.0
4042
# via ibis-framework
4143
attrs==23.2.0
@@ -57,6 +59,8 @@ beautifulsoup4==4.12.3
5759
# via nbconvert
5860
bidict==0.23.1
5961
# via ibis-framework
62+
bigtree==0.19.2
63+
# via feast (setup.py)
6064
bleach==6.1.0
6165
# via nbconvert
6266
boto3==1.34.131
@@ -117,6 +121,7 @@ cryptography==42.0.8
117121
# azure-identity
118122
# azure-storage-blob
119123
# great-expectations
124+
# jwcrypto
120125
# moto
121126
# msal
122127
# pyjwt
@@ -137,6 +142,9 @@ decorator==5.1.1
137142
defusedxml==0.7.1
138143
# via nbconvert
139144
deltalake==0.18.1
145+
# via feast (setup.py)
146+
deprecation==2.1.0
147+
# via python-keycloak
140148
dill==0.3.8
141149
distlib==0.3.8
142150
# via virtualenv
@@ -262,6 +270,7 @@ httpx==0.27.0
262270
# via
263271
# fastapi
264272
# jupyterlab
273+
# python-keycloak
265274
ibis-framework[duckdb]==9.0.0
266275
# via ibis-substrait
267276
ibis-substrait==4.0.0
@@ -375,6 +384,8 @@ jupyterlab-server==2.27.2
375384
# notebook
376385
jupyterlab-widgets==3.0.11
377386
# via ipywidgets
387+
jwcrypto==1.5.6
388+
# via python-keycloak
378389
kubernetes==20.13.0
379390
locket==1.0.0
380391
# via partd
@@ -459,6 +470,7 @@ packaging==24.1
459470
# build
460471
# dask
461472
# db-dtypes
473+
# deprecation
462474
# google-cloud-bigquery
463475
# great-expectations
464476
# gunicorn
@@ -642,6 +654,8 @@ python-dotenv==1.0.1
642654
# via uvicorn
643655
python-json-logger==2.0.7
644656
# via jupyter-events
657+
python-keycloak==4.2.2
658+
# via feast (setup.py)
645659
python-multipart==0.0.9
646660
# via fastapi
647661
pytz==2024.1
@@ -685,14 +699,18 @@ requests==2.32.3
685699
# kubernetes
686700
# moto
687701
# msal
702+
# python-keycloak
688703
# requests-oauthlib
704+
# requests-toolbelt
689705
# responses
690706
# singlestoredb
691707
# snowflake-connector-python
692708
# sphinx
693709
# trino
694710
requests-oauthlib==2.0.0
695711
# via kubernetes
712+
requests-toolbelt==1.0.0
713+
# via python-keycloak
696714
responses==0.25.3
697715
# via moto
698716
rfc3339-validator==0.1.4
@@ -873,6 +891,7 @@ typing-extensions==4.12.2
873891
# great-expectations
874892
# ibis-framework
875893
# ipython
894+
# jwcrypto
876895
# mypy
877896
# psycopg
878897
# psycopg-pool
@@ -948,4 +967,3 @@ yarl==1.9.4
948967
# via aiohttp
949968
zipp==3.19.1
950969
# via importlib-metadata
951-
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)