Skip to content

Commit e402ef3

Browse files
jopemachineclaude
andcommitted
refactor(BA-5733): pull client_ip from context in authenticated auth flows
Drop the ``client_ip`` field from Actions whose handlers are already authenticated (``signout``, ``my_revoke_login_session``, ``admin_revoke_login_session``) and have the service resolve it via ``current_client_ip()``, mirroring how ``current_user()`` is consumed in service logic. The auth middleware already populates the contextvar for authenticated routes, so handlers no longer have to thread the value through the Action. Unauthenticated entry points (``authorize``, ``logout``) keep the explicit ``client_ip`` Action field — the middleware does not set the contextvar before authentication, so the REST handler still extracts it from the request directly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent bdada6f commit e402ef3

5 files changed

Lines changed: 4 additions & 11 deletions

File tree

src/ai/backend/manager/api/adapters/login_session/adapter.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
from __future__ import annotations
44

5-
from ai.backend.common.contexts.client_ip import current_client_ip
65
from ai.backend.common.contexts.user import current_user
76
from ai.backend.common.dto.manager.v2.login_session.request import (
87
AdminRevokeLoginSessionInput,
@@ -129,7 +128,6 @@ async def my_revoke(self, input: MyRevokeLoginSessionInput) -> RevokeLoginSessio
129128
MyRevokeLoginSessionAction(
130129
session_id=input.session_id,
131130
user_id=me.user_id,
132-
client_ip=current_client_ip(),
133131
)
134132
)
135133
return RevokeLoginSessionPayload(success=action_result.success)
@@ -139,7 +137,6 @@ async def admin_revoke(self, input: AdminRevokeLoginSessionInput) -> RevokeLogin
139137
action_result = await self._processors.auth.admin_revoke_login_session.wait_for_complete(
140138
AdminRevokeLoginSessionAction(
141139
session_id=input.session_id,
142-
client_ip=current_client_ip(),
143140
)
144141
)
145142
return RevokeLoginSessionPayload(success=action_result.success)

src/ai/backend/manager/api/rest/auth/handler.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
from aiohttp import web
1616

1717
from ai.backend.common.api_handlers import APIResponse, BodyParam, QueryParam
18-
from ai.backend.common.contexts.client_ip import current_client_ip
1918
from ai.backend.common.dto.manager.auth.request import (
2019
AuthorizeRequest,
2120
GetRoleRequest,
@@ -225,7 +224,6 @@ async def signout(self, body: BodyParam[SignoutRequest], ctx: UserContext) -> AP
225224
requester_email=ctx.user_email,
226225
email=params.email,
227226
password=params.password,
228-
client_ip=current_client_ip(),
229227
)
230228
)
231229
return APIResponse.build(HTTPStatus.OK, SignoutResponse())

src/ai/backend/manager/services/auth/actions/revoke_login_session.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
@dataclass
1111
class AdminRevokeLoginSessionAction(AuthAction):
1212
session_id: UUID
13-
client_ip: str | None = None
1413

1514
@override
1615
def entity_id(self) -> str | None:
@@ -26,7 +25,6 @@ def operation_type(cls) -> ActionOperationType:
2625
class MyRevokeLoginSessionAction(AuthAction):
2726
session_id: UUID
2827
user_id: UUID
29-
client_ip: str | None = None
3028

3129
@override
3230
def entity_id(self) -> str | None:

src/ai/backend/manager/services/auth/actions/signout.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ class SignoutAction(AuthAction):
1414
requester_email: str
1515
email: str
1616
password: str
17-
client_ip: str | None = None
1817

1918
@override
2019
def entity_id(self) -> str | None:

src/ai/backend/manager/services/auth/service.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
LoginSessionInner,
1616
LoginSessionTokenData,
1717
)
18+
from ai.backend.common.contexts.client_ip import current_client_ip
1819
from ai.backend.common.dto.manager.auth.types import AuthTokenType
1920
from ai.backend.common.exception import InvalidAPIParameters, UserResourcePolicyNotFound
2021
from ai.backend.common.plugin.hook import ALL_COMPLETED, FIRST_COMPLETED, PASSED, HookPluginContext
@@ -555,7 +556,7 @@ async def admin_revoke_login_session(
555556
self, action: AdminRevokeLoginSessionAction
556557
) -> RevokeLoginSessionActionResult:
557558
session_token = await self._auth_repository.delete_login_session_by_id(
558-
action.session_id, LoginAttemptResult.REVOKED_BY_ADMIN, action.client_ip
559+
action.session_id, LoginAttemptResult.REVOKED_BY_ADMIN, current_client_ip()
559560
)
560561
await self._valkey_session_client.delete_login_session(session_token)
561562
return RevokeLoginSessionActionResult(success=True)
@@ -567,7 +568,7 @@ async def my_revoke_login_session(
567568
if session_data.user_id != action.user_id:
568569
raise GenericForbidden("You can only revoke your own login sessions.")
569570
session_token = await self._auth_repository.delete_login_session_by_id(
570-
action.session_id, LoginAttemptResult.REVOKED_BY_USER, action.client_ip
571+
action.session_id, LoginAttemptResult.REVOKED_BY_USER, current_client_ip()
571572
)
572573
await self._valkey_session_client.delete_login_session(session_token)
573574
return RevokeLoginSessionActionResult(success=True)
@@ -588,7 +589,7 @@ async def signout(self, action: SignoutAction) -> SignoutActionResult:
588589
action.password,
589590
)
590591
deleted_tokens = await self._auth_repository.delete_user_login_sessions(
591-
action.user_id, action.domain_name, LoginAttemptResult.LOGOUT, action.client_ip
592+
action.user_id, action.domain_name, LoginAttemptResult.LOGOUT, current_client_ip()
592593
)
593594
for token in deleted_tokens:
594595
await self._valkey_session_client.delete_login_session(token)

0 commit comments

Comments
 (0)