Skip to content

Commit 18ce938

Browse files
committed
manager
1 parent a148164 commit 18ce938

File tree

1 file changed

+63
-64
lines changed
  • services/web/server/src/simcore_service_webserver/users/_controller/rest

1 file changed

+63
-64
lines changed

services/web/server/src/simcore_service_webserver/users/_controller/rest/users_rest.py

Lines changed: 63 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,55 @@ class PhoneRegistrationData(TypedDict):
5858
status: Literal["pending_confirmation"]
5959

6060

61+
class PhoneRegistrationSessionManager:
62+
def __init__(self, session: Session, user_id: UserID, product_name: str):
63+
self._session = session
64+
self._user_id = user_id
65+
self._product_name = product_name
66+
67+
def start_registration(self, phone: str) -> None:
68+
phone_data: PhoneRegistrationData = {
69+
"user_id": self._user_id,
70+
"phone": phone,
71+
"status": "pending_confirmation",
72+
}
73+
self._session[_PHONE_REGISTRATION_KEY] = phone_data
74+
self._session[_PHONE_CODE_KEY] = _PHONE_CODE_VALUE_FAKE
75+
self._session[_PHONE_PENDING_KEY] = True
76+
77+
def validate_pending_registration(self) -> PhoneRegistrationData:
78+
if not self._session.get(_PHONE_PENDING_KEY):
79+
raise PhoneRegistrationPendingNotFoundError(
80+
user_id=self._user_id, product_name=self._product_name
81+
)
82+
83+
phone_registration: PhoneRegistrationData | None = self._session.get(
84+
_PHONE_REGISTRATION_KEY
85+
)
86+
if not phone_registration or phone_registration["user_id"] != self._user_id:
87+
raise PhoneRegistrationSessionInvalidError(
88+
user_id=self._user_id, product_name=self._product_name
89+
)
90+
91+
return phone_registration
92+
93+
def regenerate_code(self) -> None:
94+
self.validate_pending_registration()
95+
self._session[_PHONE_CODE_KEY] = _PHONE_CODE_VALUE_FAKE
96+
97+
def validate_confirmation_code(self, provided_code: str) -> None:
98+
expected_code = self._session.get(_PHONE_CODE_KEY)
99+
if not expected_code or provided_code != expected_code:
100+
raise PhoneRegistrationCodeInvalidError(
101+
user_id=self._user_id, product_name=self._product_name
102+
)
103+
104+
def clear_session(self) -> None:
105+
self._session.pop(_PHONE_REGISTRATION_KEY, None)
106+
self._session.pop(_PHONE_PENDING_KEY, None)
107+
self._session.pop(_PHONE_CODE_KEY, None)
108+
109+
61110
routes = web.RouteTableDef()
62111

63112
#
@@ -130,52 +179,12 @@ async def my_phone_register(request: web.Request) -> web.Response:
130179
phone_register = await parse_request_body_as(MyPhoneRegister, request)
131180

132181
session = await get_session(request)
133-
134-
# Store phone registration state in session
135-
phone_data: PhoneRegistrationData = {
136-
"user_id": req_ctx.user_id,
137-
"phone": phone_register.phone,
138-
"status": "pending_confirmation",
139-
}
140-
session[_PHONE_REGISTRATION_KEY] = phone_data
141-
142-
# NOTE: In real implementation, generate and send SMS code here
143-
# For testing, we'll use a fixed code
144-
session[_PHONE_CODE_KEY] = _PHONE_CODE_VALUE_FAKE
145-
session[_PHONE_PENDING_KEY] = True
146-
147-
return web.json_response(status=status.HTTP_202_ACCEPTED)
148-
149-
150-
def _validate_pending_phone_registration(
151-
session: Session, user_id: UserID, product_name: str
152-
) -> PhoneRegistrationData:
153-
# Check if there's a pending phone registration
154-
if not session.get(_PHONE_PENDING_KEY):
155-
raise PhoneRegistrationPendingNotFoundError(
156-
user_id=user_id, product_name=product_name
157-
)
158-
159-
# Validate session belongs to current user
160-
phone_registration: PhoneRegistrationData | None = session.get(
161-
_PHONE_REGISTRATION_KEY
182+
phone_session_manager = PhoneRegistrationSessionManager(
183+
session, req_ctx.user_id, req_ctx.product_name
162184
)
163-
if not phone_registration or phone_registration["user_id"] != user_id:
164-
raise PhoneRegistrationSessionInvalidError(
165-
user_id=user_id, product_name=product_name
166-
)
167-
168-
return phone_registration
169-
185+
phone_session_manager.start_registration(phone_register.phone)
170186

171-
def _validate_confirmation_code(
172-
session: Session, provided_code: str, *, user_id: UserID, product_name: str
173-
) -> None:
174-
expected_code = session.get(_PHONE_CODE_KEY)
175-
if not expected_code or provided_code != expected_code:
176-
raise PhoneRegistrationCodeInvalidError(
177-
user_id=user_id, product_name=product_name
178-
)
187+
return web.json_response(status=status.HTTP_202_ACCEPTED)
179188

180189

181190
@routes.post(f"/{API_VTAG}/me/phone:resend", name="my_phone_resend")
@@ -185,13 +194,12 @@ def _validate_confirmation_code(
185194
@handle_rest_requests_exceptions
186195
async def my_phone_resend(request: web.Request) -> web.Response:
187196
req_ctx = UsersRequestContext.model_validate(request)
188-
session = await get_session(request)
189-
190-
_validate_pending_phone_registration(session, req_ctx.user_id, req_ctx.product_name)
191197

192-
# NOTE: In real implementation, regenerate and resend SMS code here
193-
# For testing, we'll use the same fixed code
194-
session[_PHONE_CODE_KEY] = _PHONE_CODE_VALUE_FAKE
198+
session = await get_session(request)
199+
phone_session_manager = PhoneRegistrationSessionManager(
200+
session, req_ctx.user_id, req_ctx.product_name
201+
)
202+
phone_session_manager.regenerate_code()
195203

196204
return web.json_response(status=status.HTTP_202_ACCEPTED)
197205

@@ -204,30 +212,22 @@ async def my_phone_resend(request: web.Request) -> web.Response:
204212
async def my_phone_confirm(request: web.Request) -> web.Response:
205213
req_ctx = UsersRequestContext.model_validate(request)
206214
phone_confirm = await parse_request_body_as(MyPhoneConfirm, request)
207-
session = await get_session(request)
208215

209-
phone_registration = _validate_pending_phone_registration(
216+
session = await get_session(request)
217+
phone_session_manager = PhoneRegistrationSessionManager(
210218
session, req_ctx.user_id, req_ctx.product_name
211219
)
212220

213-
_validate_confirmation_code(
214-
session,
215-
phone_confirm.code,
216-
user_id=req_ctx.user_id,
217-
product_name=req_ctx.product_name,
218-
)
221+
phone_registration = phone_session_manager.validate_pending_registration()
222+
phone_session_manager.validate_confirmation_code(phone_confirm.code)
219223

220-
# Update user's phone number in the database
221224
await _users_service.update_user_phone(
222225
request.app,
223226
user_id=req_ctx.user_id,
224227
phone=phone_registration["phone"],
225228
)
226229

227-
# Clear phone registration session data
228-
session.pop(_PHONE_REGISTRATION_KEY, None)
229-
session.pop(_PHONE_PENDING_KEY, None)
230-
session.pop(_PHONE_CODE_KEY, None)
230+
phone_session_manager.clear_session()
231231

232232
return web.json_response(status=status.HTTP_204_NO_CONTENT)
233233

@@ -256,4 +256,3 @@ async def search_users(request: web.Request) -> web.Response:
256256
)
257257

258258
return envelope_json_response([UserGet.from_domain_model(user) for user in found])
259-
return envelope_json_response([UserGet.from_domain_model(user) for user in found])

0 commit comments

Comments
 (0)