Skip to content

Commit ae3a5e8

Browse files
🐛(ingestion) split Talensoft front and back env variables (#600)
1 parent 707c2d6 commit ae3a5e8

9 files changed

Lines changed: 99 additions & 43 deletions

File tree

env.d/ingestion-example

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
TALENTSOFT_CLIENT_ID=
2-
TALENTSOFT_CLIENT_SECRET=
3-
TALENTSOFT_BASE_URL=
1+
TALENTSOFT_FRONT_CLIENT_ID=
2+
TALENTSOFT_FRONT_CLIENT_SECRET=
3+
TALENTSOFT_FRONT_BASE_URL=
4+
5+
TALENTSOFT_BACK_CLIENT_ID=
6+
TALENTSOFT_BACK_CLIENT_SECRET=
7+
TALENTSOFT_BACK_BASE_URL=
48

59
WEB_BASE_URL=
610
WEB_API_KEY=

src/ingestion/api/config.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,13 @@ class Settings(BaseSettings):
1111
sentry_profiles_sample_rate: float | None = 0.1
1212
sentry_traces_sample_rate: float | None = 0.1
1313

14-
talentsoft_client_id: str | None = None
15-
talentsoft_client_secret: str | None = None
16-
talentsoft_base_url: str | None = None
14+
talentsoft_front_client_id: str | None = None
15+
talentsoft_front_client_secret: str | None = None
16+
talentsoft_front_base_url: str | None = None
17+
18+
talentsoft_back_client_id: str | None = None
19+
talentsoft_back_client_secret: str | None = None
20+
talentsoft_back_base_url: str | None = None
1721

1822
web_base_url: str | None = None
1923
web_api_key: str | None = None
@@ -28,9 +32,13 @@ class TestSettings(Settings):
2832
sentry_profiles_sample_rate: float | None = 0.0
2933
sentry_traces_sample_rate: float | None = 0.0
3034

31-
talentsoft_client_id: str | None = None
32-
talentsoft_client_secret: str | None = None
33-
talentsoft_base_url: str | None = None
35+
talentsoft_front_client_id: str | None = None
36+
talentsoft_front_client_secret: str | None = None
37+
talentsoft_front_base_url: str | None = None
38+
39+
talentsoft_back_client_id: str | None = None
40+
talentsoft_back_client_secret: str | None = None
41+
talentsoft_back_base_url: str | None = None
3442

3543
web_base_url: str | None = None
3644
web_api_key: str | None = None

src/ingestion/api/dependencies.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,16 @@ async def get_load_offer_details_use_case(
3737
settings: Settings = Depends(get_settings),
3838
) -> AsyncGenerator[LoadOfferDetailsUseCase | None, None]:
3939
if (
40-
not settings.talentsoft_client_id
41-
or not settings.talentsoft_client_secret
42-
or not settings.talentsoft_base_url
40+
not settings.talentsoft_front_client_id
41+
or not settings.talentsoft_front_client_secret
42+
or not settings.talentsoft_front_base_url
4343
):
4444
yield None
4545
else:
4646
config = TalentsoftConfig(
47-
base_url=settings.talentsoft_base_url,
48-
client_id=settings.talentsoft_client_id,
49-
client_secret=settings.talentsoft_client_secret,
47+
base_url=settings.talentsoft_front_base_url,
48+
client_id=settings.talentsoft_front_client_id,
49+
client_secret=settings.talentsoft_front_client_secret,
5050
)
5151
async with TalentsoftFrontClient(config=config, logger=logger) as client:
5252
yield LoadOfferDetailsUseCase(talentsoft_client=client)

src/ingestion/api/talentsoft.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,15 @@ def verify_talentsoft_signature(request: Request) -> None:
3636
if time.time() > expires_ts:
3737
raise HTTPException(status_code=403, detail="Signature has expired")
3838

39-
if not settings.talentsoft_client_id or not settings.talentsoft_client_secret:
39+
if (
40+
not settings.talentsoft_back_client_id
41+
or not settings.talentsoft_back_client_secret
42+
):
4043
raise HTTPException(
4144
status_code=500, detail="TalentSoft credentials not configured"
4245
)
4346

44-
if client_id != settings.talentsoft_client_id:
47+
if client_id != settings.talentsoft_back_client_id:
4548
raise HTTPException(status_code=403, detail="Invalid client_id")
4649

4750
# CanonicalizedTsRecHeaders: x-ts-rec-* headers, lowercased, sorted
@@ -77,7 +80,7 @@ def verify_talentsoft_signature(request: Request) -> None:
7780
+ canonicalized_resource
7881
)
7982

80-
secret = settings.talentsoft_client_secret.encode("utf-8")
83+
secret = settings.talentsoft_back_client_secret.encode("utf-8")
8184
digest = hmac.new(secret, string_to_sign.encode("utf-8"), hashlib.sha1).digest()
8285
computed = base64.b64encode(digest).decode("utf-8")
8386

src/ingestion/infrastructure/external_gateways/talentsoft_client.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ class TalentsoftConfig:
2525
client_id: str
2626
client_secret: str
2727

28+
def __post_init__(self) -> None:
29+
self.base_url = self.base_url.rstrip("/")
30+
2831

2932
class BaseTalentsoftClient(AsyncHttpClient):
3033
api_name: str

src/ingestion/tests/integration/conftest.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@
1111

1212
from api.main import create_app
1313

14-
TALENTSOFT_CLIENT_ID = "test_client_id"
15-
TALENTSOFT_CLIENT_SECRET = "test_client_secret"
16-
TALENTSOFT_BASE_URL = "https://talentsoft.example.com"
14+
TALENTSOFT_BACK_CLIENT_ID = "test_back_client_id"
15+
TALENTSOFT_BACK_CLIENT_SECRET = "test_back_client_secret"
16+
TALENTSOFT_BACK_BASE_URL = "https://talentsoft-back.example.com"
17+
TALENTSOFT_FRONT_CLIENT_ID = "test_front_client_id"
18+
TALENTSOFT_FRONT_CLIENT_SECRET = "test_front_client_secret"
19+
TALENTSOFT_FRONT_BASE_URL = "https://talentsoft-front.example.com"
1720
WEB_BASE_URL = "https://web.example.com"
1821
WEB_API_KEY = "test-web-api-key"
1922
WEBHOOK_PATH = "/webhooks/talentsoft"
@@ -22,18 +25,21 @@
2225
@pytest.fixture
2326
def test_client(monkeypatch):
2427
monkeypatch.setenv("TESTING", "true")
25-
monkeypatch.delenv("TALENTSOFT_CLIENT_ID", raising=False)
26-
monkeypatch.delenv("TALENTSOFT_CLIENT_SECRET", raising=False)
28+
monkeypatch.delenv("TALENTSOFT_BACK_CLIENT_ID", raising=False)
29+
monkeypatch.delenv("TALENTSOFT_BACK_CLIENT_SECRET", raising=False)
2730
app = create_app()
2831
return TestClient(app)
2932

3033

3134
@pytest.fixture
3235
def talentsoft_client(monkeypatch):
3336
monkeypatch.setenv("TESTING", "true")
34-
monkeypatch.setenv("TALENTSOFT_CLIENT_ID", TALENTSOFT_CLIENT_ID)
35-
monkeypatch.setenv("TALENTSOFT_CLIENT_SECRET", TALENTSOFT_CLIENT_SECRET)
36-
monkeypatch.setenv("TALENTSOFT_BASE_URL", TALENTSOFT_BASE_URL)
37+
monkeypatch.setenv("TALENTSOFT_BACK_CLIENT_ID", TALENTSOFT_BACK_CLIENT_ID)
38+
monkeypatch.setenv("TALENTSOFT_BACK_CLIENT_SECRET", TALENTSOFT_BACK_CLIENT_SECRET)
39+
monkeypatch.setenv("TALENTSOFT_BACK_BASE_URL", TALENTSOFT_BACK_BASE_URL)
40+
monkeypatch.setenv("TALENTSOFT_FRONT_CLIENT_ID", TALENTSOFT_FRONT_CLIENT_ID)
41+
monkeypatch.setenv("TALENTSOFT_FRONT_CLIENT_SECRET", TALENTSOFT_FRONT_CLIENT_SECRET)
42+
monkeypatch.setenv("TALENTSOFT_FRONT_BASE_URL", TALENTSOFT_FRONT_BASE_URL)
3743
monkeypatch.setenv("WEB_BASE_URL", WEB_BASE_URL)
3844
monkeypatch.setenv("WEB_API_KEY", WEB_API_KEY)
3945
app = create_app()
@@ -81,13 +87,13 @@ def make_signature(
8187
+ canonicalized_resource
8288
)
8389

84-
secret = TALENTSOFT_CLIENT_SECRET.encode("utf-8")
90+
secret = TALENTSOFT_BACK_CLIENT_SECRET.encode("utf-8")
8591
digest = hmac.new(secret, string_to_sign.encode("utf-8"), hashlib.sha1).digest()
8692
return base64.b64encode(digest).decode("utf-8")
8793

8894

8995
def valid_query_items() -> list[tuple[str, str]]:
90-
return [("client_id", TALENTSOFT_CLIENT_ID)]
96+
return [("client_id", TALENTSOFT_BACK_CLIENT_ID)]
9197

9298

9399
def valid_ts_rec_headers(expires: int | None = None) -> dict[str, str]:

src/ingestion/tests/integration/test_webhook_archive.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
from api.main import create_app
66
from tests.integration.conftest import (
7-
TALENTSOFT_CLIENT_ID,
8-
TALENTSOFT_CLIENT_SECRET,
7+
TALENTSOFT_BACK_CLIENT_ID,
8+
TALENTSOFT_BACK_CLIENT_SECRET,
99
WEB_API_KEY,
1010
WEB_BASE_URL,
1111
make_signed_request,
@@ -69,8 +69,8 @@ async def test_other_event_type_does_not_call_archive(
6969
@pytest.mark.asyncio
7070
async def test_web_service_not_configured_returns_500(monkeypatch):
7171
monkeypatch.setenv("TESTING", "true")
72-
monkeypatch.setenv("TALENTSOFT_CLIENT_ID", TALENTSOFT_CLIENT_ID)
73-
monkeypatch.setenv("TALENTSOFT_CLIENT_SECRET", TALENTSOFT_CLIENT_SECRET)
72+
monkeypatch.setenv("TALENTSOFT_BACK_CLIENT_ID", TALENTSOFT_BACK_CLIENT_ID)
73+
monkeypatch.setenv("TALENTSOFT_BACK_CLIENT_SECRET", TALENTSOFT_BACK_CLIENT_SECRET)
7474
monkeypatch.delenv("WEB_BASE_URL", raising=False)
7575
monkeypatch.delenv("WEB_API_KEY", raising=False)
7676
app = create_app()

src/ingestion/tests/integration/test_webhook_load_offer.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,19 @@
44

55
from api.main import create_app
66
from tests.integration.conftest import (
7-
TALENTSOFT_BASE_URL,
8-
TALENTSOFT_CLIENT_ID,
9-
TALENTSOFT_CLIENT_SECRET,
7+
TALENTSOFT_BACK_CLIENT_ID,
8+
TALENTSOFT_BACK_CLIENT_SECRET,
9+
TALENTSOFT_FRONT_BASE_URL,
10+
TALENTSOFT_FRONT_CLIENT_ID,
11+
TALENTSOFT_FRONT_CLIENT_SECRET,
1012
WEB_API_KEY,
1113
WEB_BASE_URL,
1214
make_signed_request,
1315
)
1416

1517
REFERENCE = "2024-VACANCY-001"
16-
TOKEN_URL = f"{TALENTSOFT_BASE_URL}/api/token"
17-
DETAIL_OFFER_URL = f"{TALENTSOFT_BASE_URL}/api/v2/offers/getoffer"
18+
TOKEN_URL = f"{TALENTSOFT_FRONT_BASE_URL}/api/token"
19+
DETAIL_OFFER_URL = f"{TALENTSOFT_FRONT_BASE_URL}/api/v2/offers/getoffer"
1820

1921

2022
def _coded_object():
@@ -104,9 +106,11 @@ async def test_vacancy_update_fetches_offer_details(
104106
@pytest.mark.asyncio
105107
async def test_vacancy_new_talentsoft_not_configured_returns_500(monkeypatch):
106108
monkeypatch.setenv("TESTING", "true")
107-
monkeypatch.setenv("TALENTSOFT_CLIENT_ID", TALENTSOFT_CLIENT_ID)
108-
monkeypatch.setenv("TALENTSOFT_CLIENT_SECRET", TALENTSOFT_CLIENT_SECRET)
109-
monkeypatch.delenv("TALENTSOFT_BASE_URL", raising=False)
109+
monkeypatch.setenv("TALENTSOFT_BACK_CLIENT_ID", TALENTSOFT_BACK_CLIENT_ID)
110+
monkeypatch.setenv("TALENTSOFT_BACK_CLIENT_SECRET", TALENTSOFT_BACK_CLIENT_SECRET)
111+
monkeypatch.setenv("TALENTSOFT_FRONT_CLIENT_ID", TALENTSOFT_FRONT_CLIENT_ID)
112+
monkeypatch.setenv("TALENTSOFT_FRONT_CLIENT_SECRET", TALENTSOFT_FRONT_CLIENT_SECRET)
113+
monkeypatch.delenv("TALENTSOFT_FRONT_BASE_URL", raising=False)
110114
monkeypatch.setenv("WEB_BASE_URL", WEB_BASE_URL)
111115
monkeypatch.setenv("WEB_API_KEY", WEB_API_KEY)
112116
app = create_app()
@@ -124,9 +128,11 @@ async def test_vacancy_new_talentsoft_api_error_propagates(
124128
monkeypatch, httpx_mock: HTTPXMock
125129
):
126130
monkeypatch.setenv("TESTING", "true")
127-
monkeypatch.setenv("TALENTSOFT_CLIENT_ID", TALENTSOFT_CLIENT_ID)
128-
monkeypatch.setenv("TALENTSOFT_CLIENT_SECRET", TALENTSOFT_CLIENT_SECRET)
129-
monkeypatch.setenv("TALENTSOFT_BASE_URL", TALENTSOFT_BASE_URL)
131+
monkeypatch.setenv("TALENTSOFT_BACK_CLIENT_ID", TALENTSOFT_BACK_CLIENT_ID)
132+
monkeypatch.setenv("TALENTSOFT_BACK_CLIENT_SECRET", TALENTSOFT_BACK_CLIENT_SECRET)
133+
monkeypatch.setenv("TALENTSOFT_FRONT_CLIENT_ID", TALENTSOFT_FRONT_CLIENT_ID)
134+
monkeypatch.setenv("TALENTSOFT_FRONT_CLIENT_SECRET", TALENTSOFT_FRONT_CLIENT_SECRET)
135+
monkeypatch.setenv("TALENTSOFT_FRONT_BASE_URL", TALENTSOFT_FRONT_BASE_URL)
130136
monkeypatch.setenv("WEB_BASE_URL", WEB_BASE_URL)
131137
monkeypatch.setenv("WEB_API_KEY", WEB_API_KEY)
132138
app = create_app()

src/ingestion/tests/unit/external_gateways/test_talentsoft_client.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,32 @@
1818
fake = Faker()
1919

2020

21+
class TestTalentsoftConfig:
22+
def test_base_url_trailing_slash_is_stripped(self):
23+
config = TalentsoftConfig(
24+
base_url="https://example.com/",
25+
client_id=fake.uuid4(),
26+
client_secret=fake.uuid4(),
27+
)
28+
assert config.base_url == "https://example.com"
29+
30+
def test_base_url_without_trailing_slash_is_unchanged(self):
31+
config = TalentsoftConfig(
32+
base_url="https://example.com",
33+
client_id=fake.uuid4(),
34+
client_secret=fake.uuid4(),
35+
)
36+
assert config.base_url == "https://example.com"
37+
38+
def test_base_url_multiple_trailing_slashes_are_stripped(self):
39+
config = TalentsoftConfig(
40+
base_url="https://example.com///",
41+
client_id=fake.uuid4(),
42+
client_secret=fake.uuid4(),
43+
)
44+
assert config.base_url == "https://example.com"
45+
46+
2147
@pytest.fixture(name="talentsoft_client")
2248
def talentsoft_client_fixture():
2349
config = TalentsoftConfig(

0 commit comments

Comments
 (0)