square-authentication 10.0.0__py3-none-any.whl → 10.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- square_authentication/routes/core.py +166 -3002
- square_authentication/routes/profile.py +38 -579
- square_authentication/routes/utility.py +7 -37
- square_authentication/utils/routes/__init__.py +0 -0
- square_authentication/utils/routes/core.py +3251 -0
- square_authentication/utils/routes/profile.py +647 -0
- square_authentication/utils/routes/utility.py +55 -0
- {square_authentication-10.0.0.dist-info → square_authentication-10.0.2.dist-info}/METADATA +7 -2
- {square_authentication-10.0.0.dist-info → square_authentication-10.0.2.dist-info}/RECORD +12 -8
- {square_authentication-10.0.0.dist-info → square_authentication-10.0.2.dist-info}/WHEEL +0 -0
- {square_authentication-10.0.0.dist-info → square_authentication-10.0.2.dist-info}/licenses/LICENSE +0 -0
- {square_authentication-10.0.0.dist-info → square_authentication-10.0.2.dist-info}/top_level.txt +0 -0
@@ -1,64 +1,15 @@
|
|
1
|
-
import copy
|
2
|
-
import io
|
3
|
-
import mimetypes
|
4
|
-
import random
|
5
|
-
import re
|
6
|
-
import uuid
|
7
|
-
from datetime import datetime, timedelta, timezone
|
8
1
|
from typing import Annotated, List
|
9
2
|
|
10
|
-
import bcrypt
|
11
|
-
import jwt
|
12
3
|
from fastapi import APIRouter, Header, HTTPException, status
|
13
4
|
from fastapi.params import Query
|
14
5
|
from fastapi.responses import JSONResponse
|
15
|
-
from
|
16
|
-
from google.oauth2 import id_token
|
17
|
-
from requests import HTTPError
|
18
|
-
from square_commons import get_api_output_in_standard_format, send_email_using_mailgun
|
19
|
-
from square_commons.api_utils import make_request
|
20
|
-
from square_database_helper.pydantic_models import FilterConditionsV0, FiltersV0
|
21
|
-
from square_database_structure.square import global_string_database_name
|
22
|
-
from square_database_structure.square.authentication import global_string_schema_name
|
6
|
+
from square_commons import get_api_output_in_standard_format
|
23
7
|
from square_database_structure.square.authentication.enums import (
|
24
8
|
RecoveryMethodEnum,
|
25
|
-
AuthProviderEnum,
|
26
|
-
VerificationCodeTypeEnum,
|
27
9
|
)
|
28
|
-
from square_database_structure.square.authentication.tables import (
|
29
|
-
User,
|
30
|
-
UserApp,
|
31
|
-
UserCredential,
|
32
|
-
UserSession,
|
33
|
-
UserProfile,
|
34
|
-
UserRecoveryMethod,
|
35
|
-
UserAuthProvider,
|
36
|
-
UserVerificationCode,
|
37
|
-
)
|
38
|
-
from square_database_structure.square.email import (
|
39
|
-
global_string_schema_name as email_schema_name,
|
40
|
-
)
|
41
|
-
from square_database_structure.square.email.enums import EmailTypeEnum, EmailStatusEnum
|
42
|
-
from square_database_structure.square.email.tables import EmailLog
|
43
|
-
from square_database_structure.square.public import (
|
44
|
-
global_string_schema_name as global_string_public_schema_name,
|
45
|
-
)
|
46
|
-
from square_database_structure.square.public.tables import App
|
47
10
|
|
48
11
|
from square_authentication.configuration import (
|
49
|
-
config_int_access_token_valid_minutes,
|
50
|
-
config_int_refresh_token_valid_minutes,
|
51
|
-
config_str_secret_key_for_access_token,
|
52
|
-
config_str_secret_key_for_refresh_token,
|
53
12
|
global_object_square_logger,
|
54
|
-
global_object_square_database_helper,
|
55
|
-
MAIL_GUN_API_KEY,
|
56
|
-
GOOGLE_AUTH_PLATFORM_CLIENT_ID,
|
57
|
-
NUMBER_OF_RECOVERY_CODES,
|
58
|
-
NUMBER_OF_DIGITS_IN_EMAIL_PASSWORD_RESET_CODE,
|
59
|
-
EXPIRY_TIME_FOR_EMAIL_PASSWORD_RESET_CODE_IN_SECONDS,
|
60
|
-
global_object_square_file_store_helper,
|
61
|
-
RESEND_COOL_DOWN_TIME_FOR_EMAIL_PASSWORD_RESET_CODE_IN_SECONDS,
|
62
13
|
)
|
63
14
|
from square_authentication.messages import messages
|
64
15
|
from square_authentication.pydantic_models.core import (
|
@@ -73,8 +24,26 @@ from square_authentication.pydantic_models.core import (
|
|
73
24
|
ResetPasswordAndLoginUsingResetEmailCodeV0,
|
74
25
|
RegisterLoginGoogleV0,
|
75
26
|
)
|
76
|
-
from square_authentication.utils.core import
|
77
|
-
|
27
|
+
from square_authentication.utils.routes.core import (
|
28
|
+
util_register_username_v0,
|
29
|
+
util_register_login_google_v0,
|
30
|
+
util_get_user_details_v0,
|
31
|
+
util_update_user_app_ids_v0,
|
32
|
+
util_login_username_v0,
|
33
|
+
util_generate_access_token_v0,
|
34
|
+
util_logout_v0,
|
35
|
+
util_logout_apps_v0,
|
36
|
+
util_logout_all_v0,
|
37
|
+
util_update_username_v0,
|
38
|
+
util_delete_user_v0,
|
39
|
+
util_update_password_v0,
|
40
|
+
util_validate_and_get_payload_from_token_v0,
|
41
|
+
util_update_user_recovery_methods_v0,
|
42
|
+
util_generate_account_backup_codes_v0,
|
43
|
+
util_reset_password_and_login_using_backup_code_v0,
|
44
|
+
util_send_reset_password_email_v0,
|
45
|
+
util_reset_password_and_login_using_reset_email_code_v0,
|
46
|
+
)
|
78
47
|
|
79
48
|
router = APIRouter(
|
80
49
|
tags=["core"],
|
@@ -86,210 +55,19 @@ router = APIRouter(
|
|
86
55
|
async def register_username_v0(
|
87
56
|
body: RegisterUsernameV0,
|
88
57
|
):
|
89
|
-
username = body.username
|
90
|
-
password = body.password
|
91
|
-
app_id = body.app_id
|
92
|
-
|
93
|
-
local_str_user_id = None
|
94
|
-
local_str_access_token = None
|
95
|
-
local_str_refresh_token = None
|
96
|
-
local_object_refresh_token_expiry_time = None
|
97
|
-
username = username.lower()
|
98
58
|
try:
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
log=f"username '{username}' is invalid. it must start and end with a letter, "
|
108
|
-
f"contain only lowercase letters, numbers, underscores, or hyphens, "
|
109
|
-
f"and not have consecutive separators.",
|
110
|
-
)
|
111
|
-
raise HTTPException(
|
112
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
113
|
-
detail=output_content,
|
114
|
-
)
|
115
|
-
local_list_response_user_creds = (
|
116
|
-
global_object_square_database_helper.get_rows_v0(
|
117
|
-
database_name=global_string_database_name,
|
118
|
-
schema_name=global_string_schema_name,
|
119
|
-
table_name=User.__tablename__,
|
120
|
-
filters=FiltersV0(
|
121
|
-
root={User.user_username.name: FilterConditionsV0(eq=username)}
|
122
|
-
),
|
123
|
-
)["data"]["main"]
|
124
|
-
)
|
125
|
-
if len(local_list_response_user_creds) > 0:
|
126
|
-
output_content = get_api_output_in_standard_format(
|
127
|
-
message=messages["USERNAME_ALREADY_EXISTS"],
|
128
|
-
log=f"an account with the username {username} already exists.",
|
129
|
-
)
|
130
|
-
raise HTTPException(
|
131
|
-
status_code=status.HTTP_409_CONFLICT,
|
132
|
-
detail=output_content,
|
133
|
-
)
|
134
|
-
|
135
|
-
"""
|
136
|
-
main process
|
137
|
-
"""
|
138
|
-
# entry in user table
|
139
|
-
local_list_response_user = global_object_square_database_helper.insert_rows_v0(
|
140
|
-
data=[
|
141
|
-
{
|
142
|
-
User.user_username.name: username,
|
143
|
-
}
|
144
|
-
],
|
145
|
-
database_name=global_string_database_name,
|
146
|
-
schema_name=global_string_schema_name,
|
147
|
-
table_name=User.__tablename__,
|
148
|
-
)["data"]["main"]
|
149
|
-
local_str_user_id = local_list_response_user[0][User.user_id.name]
|
150
|
-
|
151
|
-
# entry in user auth provider table
|
152
|
-
global_object_square_database_helper.insert_rows_v0(
|
153
|
-
data=[
|
154
|
-
{
|
155
|
-
UserAuthProvider.user_id.name: local_str_user_id,
|
156
|
-
UserAuthProvider.auth_provider.name: AuthProviderEnum.SELF.value,
|
157
|
-
}
|
158
|
-
],
|
159
|
-
database_name=global_string_database_name,
|
160
|
-
schema_name=global_string_schema_name,
|
161
|
-
table_name=UserAuthProvider.__tablename__,
|
162
|
-
)
|
163
|
-
|
164
|
-
# entry in user profile table
|
165
|
-
global_object_square_database_helper.insert_rows_v0(
|
166
|
-
database_name=global_string_database_name,
|
167
|
-
schema_name=global_string_schema_name,
|
168
|
-
table_name=UserProfile.__tablename__,
|
169
|
-
data=[
|
170
|
-
{
|
171
|
-
UserProfile.user_id.name: local_str_user_id,
|
172
|
-
}
|
173
|
-
],
|
174
|
-
)
|
175
|
-
|
176
|
-
# entry in credential table
|
177
|
-
|
178
|
-
# hash password
|
179
|
-
local_str_hashed_password = bcrypt.hashpw(
|
180
|
-
password.encode("utf-8"), bcrypt.gensalt()
|
181
|
-
).decode("utf-8")
|
182
|
-
|
183
|
-
global_object_square_database_helper.insert_rows_v0(
|
184
|
-
data=[
|
185
|
-
{
|
186
|
-
UserCredential.user_id.name: local_str_user_id,
|
187
|
-
UserCredential.user_credential_hashed_password.name: local_str_hashed_password,
|
188
|
-
}
|
189
|
-
],
|
190
|
-
database_name=global_string_database_name,
|
191
|
-
schema_name=global_string_schema_name,
|
192
|
-
table_name=UserCredential.__tablename__,
|
193
|
-
)
|
194
|
-
if app_id is not None:
|
195
|
-
# assign app to user
|
196
|
-
global_object_square_database_helper.insert_rows_v0(
|
197
|
-
database_name=global_string_database_name,
|
198
|
-
schema_name=global_string_schema_name,
|
199
|
-
table_name=UserApp.__tablename__,
|
200
|
-
data=[
|
201
|
-
{
|
202
|
-
UserApp.user_id.name: local_str_user_id,
|
203
|
-
UserApp.app_id.name: app_id,
|
204
|
-
}
|
205
|
-
],
|
206
|
-
)
|
207
|
-
|
208
|
-
# return new access token and refresh token
|
209
|
-
# create access token
|
210
|
-
local_dict_access_token_payload = {
|
211
|
-
"app_id": app_id,
|
212
|
-
"user_id": local_str_user_id,
|
213
|
-
"exp": datetime.now(timezone.utc)
|
214
|
-
+ timedelta(minutes=config_int_access_token_valid_minutes),
|
215
|
-
}
|
216
|
-
local_str_access_token = jwt.encode(
|
217
|
-
local_dict_access_token_payload,
|
218
|
-
config_str_secret_key_for_access_token,
|
219
|
-
)
|
220
|
-
|
221
|
-
# create refresh token
|
222
|
-
local_object_refresh_token_expiry_time = datetime.now(
|
223
|
-
timezone.utc
|
224
|
-
) + timedelta(minutes=config_int_refresh_token_valid_minutes)
|
225
|
-
|
226
|
-
local_dict_refresh_token_payload = {
|
227
|
-
"app_id": app_id,
|
228
|
-
"user_id": local_str_user_id,
|
229
|
-
"exp": local_object_refresh_token_expiry_time,
|
230
|
-
}
|
231
|
-
local_str_refresh_token = jwt.encode(
|
232
|
-
local_dict_refresh_token_payload,
|
233
|
-
config_str_secret_key_for_refresh_token,
|
234
|
-
)
|
235
|
-
# entry in user session table
|
236
|
-
global_object_square_database_helper.insert_rows_v0(
|
237
|
-
data=[
|
238
|
-
{
|
239
|
-
UserSession.user_id.name: local_str_user_id,
|
240
|
-
UserSession.app_id.name: app_id,
|
241
|
-
UserSession.user_session_refresh_token.name: local_str_refresh_token,
|
242
|
-
UserSession.user_session_expiry_time.name: local_object_refresh_token_expiry_time.strftime(
|
243
|
-
"%Y-%m-%d %H:%M:%S.%f+00"
|
244
|
-
),
|
245
|
-
}
|
246
|
-
],
|
247
|
-
database_name=global_string_database_name,
|
248
|
-
schema_name=global_string_schema_name,
|
249
|
-
table_name=UserSession.__tablename__,
|
250
|
-
)
|
251
|
-
"""
|
252
|
-
return value
|
253
|
-
"""
|
254
|
-
output_content = get_api_output_in_standard_format(
|
255
|
-
message=messages["REGISTRATION_SUCCESSFUL"],
|
256
|
-
data={
|
257
|
-
"main": {
|
258
|
-
"user_id": local_str_user_id,
|
259
|
-
"username": username,
|
260
|
-
"app_id": app_id,
|
261
|
-
"access_token": local_str_access_token,
|
262
|
-
"refresh_token": local_str_refresh_token,
|
263
|
-
"refresh_token_expiry_time": local_object_refresh_token_expiry_time.isoformat(),
|
264
|
-
},
|
265
|
-
},
|
266
|
-
)
|
267
|
-
return JSONResponse(
|
268
|
-
status_code=status.HTTP_201_CREATED,
|
269
|
-
content=output_content,
|
270
|
-
)
|
271
|
-
except HTTPException as http_exception:
|
272
|
-
global_object_square_logger.logger.error(http_exception, exc_info=True)
|
273
|
-
return JSONResponse(
|
274
|
-
status_code=http_exception.status_code, content=http_exception.detail
|
275
|
-
)
|
59
|
+
return util_register_username_v0(
|
60
|
+
username=body.username,
|
61
|
+
password=body.password,
|
62
|
+
app_id=body.app_id,
|
63
|
+
)
|
64
|
+
except HTTPException as he:
|
65
|
+
global_object_square_logger.logger.error(he, exc_info=True)
|
66
|
+
return JSONResponse(status_code=he.status_code, content=he.detail)
|
276
67
|
except Exception as e:
|
277
68
|
global_object_square_logger.logger.error(e, exc_info=True)
|
278
|
-
"""
|
279
|
-
rollback logic
|
280
|
-
"""
|
281
|
-
if local_str_user_id:
|
282
|
-
global_object_square_database_helper.delete_rows_v0(
|
283
|
-
database_name=global_string_database_name,
|
284
|
-
schema_name=global_string_schema_name,
|
285
|
-
table_name=User.__tablename__,
|
286
|
-
filters=FiltersV0(
|
287
|
-
root={User.user_id.name: FilterConditionsV0(eq=local_str_user_id)}
|
288
|
-
),
|
289
|
-
)
|
290
69
|
output_content = get_api_output_in_standard_format(
|
291
|
-
message=messages["GENERIC_500"],
|
292
|
-
log=str(e),
|
70
|
+
message=messages["GENERIC_500"], log=str(e)
|
293
71
|
)
|
294
72
|
return JSONResponse(
|
295
73
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
@@ -298,361 +76,22 @@ async def register_username_v0(
|
|
298
76
|
|
299
77
|
@router.post("/register_login_google/v0")
|
300
78
|
async def register_login_google_v0(body: RegisterLoginGoogleV0):
|
301
|
-
app_id = body.app_id
|
302
|
-
google_id = body.google_id
|
303
|
-
assign_app_id_if_missing = body.assign_app_id_if_missing
|
304
|
-
was_new_user = False
|
305
79
|
try:
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
GOOGLE_AUTH_PLATFORM_CLIENT_ID,
|
315
|
-
)
|
316
|
-
except Exception:
|
317
|
-
output_content = get_api_output_in_standard_format(
|
318
|
-
message=messages["GENERIC_400"],
|
319
|
-
log="Google id is invalid.",
|
320
|
-
)
|
321
|
-
raise HTTPException(
|
322
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
323
|
-
detail=output_content,
|
324
|
-
)
|
325
|
-
|
326
|
-
# validate if email is verified
|
327
|
-
if id_info.get("email_verified") is not True:
|
328
|
-
output_content = get_api_output_in_standard_format(
|
329
|
-
message=messages["EMAIL_NOT_VERIFIED"],
|
330
|
-
log="Google account email is not verified.",
|
331
|
-
)
|
332
|
-
raise HTTPException(
|
333
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
334
|
-
detail=output_content,
|
335
|
-
)
|
336
|
-
"""
|
337
|
-
processing
|
338
|
-
"""
|
339
|
-
google_sub = id_info["sub"]
|
340
|
-
email = id_info.get("email")
|
341
|
-
given_name = id_info.get("given_name")
|
342
|
-
family_name = id_info.get("family_name")
|
343
|
-
|
344
|
-
profile_picture = id_info.get("picture")
|
345
|
-
|
346
|
-
# check if user exists
|
347
|
-
user_rows = global_object_square_database_helper.get_rows_v0(
|
348
|
-
database_name=global_string_database_name,
|
349
|
-
schema_name=global_string_schema_name,
|
350
|
-
table_name=UserAuthProvider.__tablename__,
|
351
|
-
filters=FiltersV0(
|
352
|
-
root={
|
353
|
-
UserAuthProvider.auth_provider_user_id.name: FilterConditionsV0(
|
354
|
-
eq=google_sub
|
355
|
-
),
|
356
|
-
UserAuthProvider.auth_provider.name: FilterConditionsV0(
|
357
|
-
eq=AuthProviderEnum.GOOGLE.value
|
358
|
-
),
|
359
|
-
}
|
360
|
-
),
|
361
|
-
)["data"]["main"]
|
362
|
-
|
363
|
-
if user_rows:
|
364
|
-
# login
|
365
|
-
|
366
|
-
# validate if app_id is assigned to user
|
367
|
-
# this will also validate if app_id is valid
|
368
|
-
local_str_user_id = user_rows[0][User.user_id.name]
|
369
|
-
user_record = global_object_square_database_helper.get_rows_v0(
|
370
|
-
database_name=global_string_database_name,
|
371
|
-
schema_name=global_string_schema_name,
|
372
|
-
table_name=User.__tablename__,
|
373
|
-
filters=FiltersV0(
|
374
|
-
root={User.user_id.name: FilterConditionsV0(eq=local_str_user_id)}
|
375
|
-
),
|
376
|
-
)["data"]["main"][0]
|
377
|
-
username = user_record[User.user_username.name]
|
378
|
-
local_list_user_app_response = (
|
379
|
-
global_object_square_database_helper.get_rows_v0(
|
380
|
-
database_name=global_string_database_name,
|
381
|
-
schema_name=global_string_schema_name,
|
382
|
-
table_name=UserApp.__tablename__,
|
383
|
-
filters=FiltersV0(
|
384
|
-
root={
|
385
|
-
UserApp.user_id.name: FilterConditionsV0(
|
386
|
-
eq=local_str_user_id
|
387
|
-
),
|
388
|
-
UserApp.app_id.name: FilterConditionsV0(eq=app_id),
|
389
|
-
}
|
390
|
-
),
|
391
|
-
)["data"]["main"]
|
392
|
-
)
|
393
|
-
if len(local_list_user_app_response) == 0:
|
394
|
-
if assign_app_id_if_missing:
|
395
|
-
global_object_square_database_helper.insert_rows_v0(
|
396
|
-
database_name=global_string_database_name,
|
397
|
-
schema_name=global_string_schema_name,
|
398
|
-
table_name=UserApp.__tablename__,
|
399
|
-
data=[
|
400
|
-
{
|
401
|
-
UserApp.user_id.name: local_str_user_id,
|
402
|
-
UserApp.app_id.name: app_id,
|
403
|
-
}
|
404
|
-
],
|
405
|
-
)
|
406
|
-
else:
|
407
|
-
output_content = get_api_output_in_standard_format(
|
408
|
-
message=messages["GENERIC_400"],
|
409
|
-
log=f"user_id {local_str_user_id}({username}) not assigned to app {app_id}.",
|
410
|
-
)
|
411
|
-
raise HTTPException(
|
412
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
413
|
-
detail=output_content,
|
414
|
-
)
|
415
|
-
else:
|
416
|
-
# register
|
417
|
-
|
418
|
-
was_new_user = True
|
419
|
-
# check if account with same email address exists
|
420
|
-
profile_rows = global_object_square_database_helper.get_rows_v0(
|
421
|
-
database_name=global_string_database_name,
|
422
|
-
schema_name=global_string_schema_name,
|
423
|
-
table_name=UserProfile.__tablename__,
|
424
|
-
filters=FiltersV0(
|
425
|
-
root={
|
426
|
-
UserProfile.user_profile_email.name: FilterConditionsV0(
|
427
|
-
eq=email
|
428
|
-
)
|
429
|
-
}
|
430
|
-
),
|
431
|
-
)["data"]["main"]
|
432
|
-
if len(profile_rows) > 0:
|
433
|
-
output_content = get_api_output_in_standard_format(
|
434
|
-
message=messages["ACCOUNT_WITH_EMAIL_ALREADY_EXISTS"],
|
435
|
-
log=f"An account with the email {email} already exists.",
|
436
|
-
)
|
437
|
-
raise HTTPException(
|
438
|
-
status_code=status.HTTP_409_CONFLICT,
|
439
|
-
detail=output_content,
|
440
|
-
)
|
441
|
-
# generate a default username
|
442
|
-
username = generate_default_username_for_google_users(
|
443
|
-
family_name=family_name, given_name=given_name
|
444
|
-
)
|
445
|
-
# create user
|
446
|
-
user_rows = global_object_square_database_helper.insert_rows_v0(
|
447
|
-
database_name=global_string_database_name,
|
448
|
-
schema_name=global_string_schema_name,
|
449
|
-
table_name=User.__tablename__,
|
450
|
-
data=[
|
451
|
-
{
|
452
|
-
User.user_username.name: username,
|
453
|
-
}
|
454
|
-
],
|
455
|
-
)["data"]["main"]
|
456
|
-
local_str_user_id = user_rows[0][User.user_id.name]
|
457
|
-
|
458
|
-
# link to user_auth_provider
|
459
|
-
global_object_square_database_helper.insert_rows_v0(
|
460
|
-
database_name=global_string_database_name,
|
461
|
-
schema_name=global_string_schema_name,
|
462
|
-
table_name=UserAuthProvider.__tablename__,
|
463
|
-
data=[
|
464
|
-
{
|
465
|
-
UserAuthProvider.user_id.name: local_str_user_id,
|
466
|
-
UserAuthProvider.auth_provider.name: AuthProviderEnum.GOOGLE.value,
|
467
|
-
UserAuthProvider.auth_provider_user_id.name: google_sub,
|
468
|
-
}
|
469
|
-
],
|
470
|
-
)
|
471
|
-
# getting profile picture
|
472
|
-
if profile_picture:
|
473
|
-
try:
|
474
|
-
profile_picture_response = make_request(
|
475
|
-
"GET", profile_picture, return_type="response"
|
476
|
-
)
|
477
|
-
|
478
|
-
# finding content type and filename
|
479
|
-
headers = profile_picture_response.headers
|
480
|
-
content_type = headers.get(
|
481
|
-
"Content-Type", "application/octet-stream"
|
482
|
-
)
|
483
|
-
content_disposition = headers.get("Content-Disposition", "")
|
484
|
-
|
485
|
-
if content_disposition:
|
486
|
-
match = re.search(r'filename="([^"]+)"', content_disposition)
|
487
|
-
if match:
|
488
|
-
filename = match.group(1)
|
489
|
-
else:
|
490
|
-
filename = None
|
491
|
-
else:
|
492
|
-
filename = None
|
493
|
-
if filename is None:
|
494
|
-
global_object_square_logger.logger.warning(
|
495
|
-
f"user_id {local_str_user_id}'s profile picture from Google missing filename; guessing extension from Content-Type: {content_type}."
|
496
|
-
)
|
497
|
-
ext = (
|
498
|
-
mimetypes.guess_extension(
|
499
|
-
content_type.split(";")[0].strip()
|
500
|
-
)
|
501
|
-
or ""
|
502
|
-
)
|
503
|
-
filename = f"profile_photo{ext}"
|
504
|
-
if not ext:
|
505
|
-
filename += ".bin"
|
506
|
-
|
507
|
-
# upload bytes to square_file_storage
|
508
|
-
file_upload_response = global_object_square_file_store_helper.upload_file_using_tuple_v0(
|
509
|
-
file=(
|
510
|
-
filename,
|
511
|
-
io.BytesIO(profile_picture_response.content),
|
512
|
-
content_type,
|
513
|
-
),
|
514
|
-
system_relative_path="global/users/profile_photos",
|
515
|
-
)
|
516
|
-
user_profile_photo_storage_token = file_upload_response["data"][
|
517
|
-
"main"
|
518
|
-
]
|
519
|
-
except HTTPError:
|
520
|
-
global_object_square_logger.logger.error(
|
521
|
-
f"Failed to fetch profile picture for user_id {local_str_user_id} from google account.",
|
522
|
-
exc_info=True,
|
523
|
-
)
|
524
|
-
user_profile_photo_storage_token = None
|
525
|
-
except Exception as e:
|
526
|
-
global_object_square_logger.logger.error(
|
527
|
-
f"Error while fetching profile picture for user_id {local_str_user_id} from google account: {str(e)}",
|
528
|
-
exc_info=True,
|
529
|
-
)
|
530
|
-
user_profile_photo_storage_token = None
|
531
|
-
else:
|
532
|
-
global_object_square_logger.logger.warning(
|
533
|
-
f"user_id {local_str_user_id} has no profile picture in google account."
|
534
|
-
)
|
535
|
-
user_profile_photo_storage_token = None
|
536
|
-
# create user profile
|
537
|
-
global_object_square_database_helper.insert_rows_v0(
|
538
|
-
database_name=global_string_database_name,
|
539
|
-
schema_name=global_string_schema_name,
|
540
|
-
table_name=UserProfile.__tablename__,
|
541
|
-
data=[
|
542
|
-
{
|
543
|
-
UserProfile.user_id.name: local_str_user_id,
|
544
|
-
UserProfile.user_profile_email.name: email,
|
545
|
-
UserProfile.user_profile_email_verified.name: datetime.now(
|
546
|
-
timezone.utc
|
547
|
-
).strftime("%Y-%m-%d %H:%M:%S.%f+00"),
|
548
|
-
UserProfile.user_profile_first_name.name: given_name,
|
549
|
-
UserProfile.user_profile_last_name.name: family_name,
|
550
|
-
UserProfile.user_profile_photo_storage_token.name: user_profile_photo_storage_token,
|
551
|
-
}
|
552
|
-
],
|
553
|
-
)
|
554
|
-
|
555
|
-
# assign app if provided
|
556
|
-
if app_id is not None:
|
557
|
-
global_object_square_database_helper.insert_rows_v0(
|
558
|
-
database_name=global_string_database_name,
|
559
|
-
schema_name=global_string_schema_name,
|
560
|
-
table_name=UserApp.__tablename__,
|
561
|
-
data=[
|
562
|
-
{
|
563
|
-
UserApp.user_id.name: local_str_user_id,
|
564
|
-
UserApp.app_id.name: app_id,
|
565
|
-
}
|
566
|
-
],
|
567
|
-
)
|
568
|
-
|
569
|
-
# generate tokens
|
570
|
-
now = datetime.now(timezone.utc)
|
571
|
-
access_token_payload = {
|
572
|
-
"app_id": app_id,
|
573
|
-
"user_id": local_str_user_id,
|
574
|
-
"exp": now + timedelta(minutes=config_int_access_token_valid_minutes),
|
575
|
-
}
|
576
|
-
access_token_str = jwt.encode(
|
577
|
-
access_token_payload,
|
578
|
-
config_str_secret_key_for_access_token,
|
579
|
-
)
|
580
|
-
|
581
|
-
refresh_token_expiry = now + timedelta(
|
582
|
-
minutes=config_int_refresh_token_valid_minutes
|
583
|
-
)
|
584
|
-
refresh_token_payload = {
|
585
|
-
"app_id": app_id,
|
586
|
-
"user_id": local_str_user_id,
|
587
|
-
"exp": refresh_token_expiry,
|
588
|
-
}
|
589
|
-
refresh_token_str = jwt.encode(
|
590
|
-
refresh_token_payload,
|
591
|
-
config_str_secret_key_for_refresh_token,
|
592
|
-
)
|
593
|
-
|
594
|
-
# store refresh token
|
595
|
-
global_object_square_database_helper.insert_rows_v0(
|
596
|
-
database_name=global_string_database_name,
|
597
|
-
schema_name=global_string_schema_name,
|
598
|
-
table_name=UserSession.__tablename__,
|
599
|
-
data=[
|
600
|
-
{
|
601
|
-
UserSession.user_id.name: local_str_user_id,
|
602
|
-
UserSession.app_id.name: app_id,
|
603
|
-
UserSession.user_session_refresh_token.name: refresh_token_str,
|
604
|
-
UserSession.user_session_expiry_time.name: refresh_token_expiry.strftime(
|
605
|
-
"%Y-%m-%d %H:%M:%S.%f+00"
|
606
|
-
),
|
607
|
-
}
|
608
|
-
],
|
609
|
-
)
|
610
|
-
"""
|
611
|
-
return value
|
612
|
-
"""
|
613
|
-
if was_new_user:
|
614
|
-
message = messages["REGISTRATION_SUCCESSFUL"]
|
615
|
-
else:
|
616
|
-
message = messages["LOGIN_SUCCESSFUL"]
|
617
|
-
output_content = get_api_output_in_standard_format(
|
618
|
-
message=message,
|
619
|
-
data={
|
620
|
-
"main": {
|
621
|
-
"user_id": local_str_user_id,
|
622
|
-
"username": username,
|
623
|
-
"app_id": app_id,
|
624
|
-
"access_token": access_token_str,
|
625
|
-
"refresh_token": refresh_token_str,
|
626
|
-
"refresh_token_expiry_time": refresh_token_expiry.isoformat(),
|
627
|
-
"was_new_user": was_new_user,
|
628
|
-
},
|
629
|
-
},
|
630
|
-
)
|
631
|
-
|
632
|
-
return JSONResponse(status_code=status.HTTP_200_OK, content=output_content)
|
633
|
-
except HTTPError as http_error:
|
634
|
-
global_object_square_logger.logger.error(http_error, exc_info=True)
|
635
|
-
return JSONResponse(
|
636
|
-
status_code=http_error.response.status_code,
|
637
|
-
content=http_error.response.text,
|
638
|
-
)
|
639
|
-
except HTTPException as http_exception:
|
640
|
-
global_object_square_logger.logger.error(http_exception, exc_info=True)
|
641
|
-
return JSONResponse(
|
642
|
-
status_code=http_exception.status_code, content=http_exception.detail
|
643
|
-
)
|
80
|
+
return util_register_login_google_v0(
|
81
|
+
app_id=body.app_id,
|
82
|
+
google_id=body.google_id,
|
83
|
+
assign_app_id_if_missing=body.assign_app_id_if_missing,
|
84
|
+
)
|
85
|
+
except HTTPException as he:
|
86
|
+
global_object_square_logger.logger.error(he, exc_info=True)
|
87
|
+
return JSONResponse(status_code=he.status_code, content=he.detail)
|
644
88
|
except Exception as e:
|
645
|
-
"""
|
646
|
-
rollback logic
|
647
|
-
"""
|
648
89
|
global_object_square_logger.logger.error(e, exc_info=True)
|
649
90
|
output_content = get_api_output_in_standard_format(
|
650
|
-
message=messages["GENERIC_500"],
|
651
|
-
log=str(e),
|
91
|
+
message=messages["GENERIC_500"], log=str(e)
|
652
92
|
)
|
653
93
|
return JSONResponse(
|
654
|
-
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
655
|
-
content=output_content,
|
94
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
656
95
|
)
|
657
96
|
|
658
97
|
|
@@ -662,123 +101,17 @@ async def get_user_details_v0(
|
|
662
101
|
access_token: Annotated[str, Header()],
|
663
102
|
):
|
664
103
|
try:
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
try:
|
670
|
-
local_dict_access_token_payload = get_jwt_payload(
|
671
|
-
access_token, config_str_secret_key_for_access_token
|
672
|
-
)
|
673
|
-
except Exception as error:
|
674
|
-
output_content = get_api_output_in_standard_format(
|
675
|
-
message=messages["INCORRECT_ACCESS_TOKEN"], log=str(error)
|
676
|
-
)
|
677
|
-
raise HTTPException(
|
678
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
679
|
-
detail=output_content,
|
680
|
-
)
|
681
|
-
user_id = local_dict_access_token_payload["user_id"]
|
682
|
-
"""
|
683
|
-
main process
|
684
|
-
"""
|
685
|
-
local_list_app = global_object_square_database_helper.get_rows_v0(
|
686
|
-
database_name=global_string_database_name,
|
687
|
-
schema_name=global_string_public_schema_name,
|
688
|
-
table_name=App.__tablename__,
|
689
|
-
apply_filters=False,
|
690
|
-
filters=FiltersV0(root={}),
|
691
|
-
)["data"]["main"]
|
692
|
-
local_list_response_user_app = global_object_square_database_helper.get_rows_v0(
|
693
|
-
database_name=global_string_database_name,
|
694
|
-
schema_name=global_string_schema_name,
|
695
|
-
table_name=UserApp.__tablename__,
|
696
|
-
filters=FiltersV0(
|
697
|
-
root={UserApp.user_id.name: FilterConditionsV0(eq=user_id)}
|
698
|
-
),
|
699
|
-
)["data"]["main"]
|
700
|
-
local_list_response_user_profile = (
|
701
|
-
global_object_square_database_helper.get_rows_v0(
|
702
|
-
database_name=global_string_database_name,
|
703
|
-
schema_name=global_string_schema_name,
|
704
|
-
table_name=UserProfile.__tablename__,
|
705
|
-
filters=FiltersV0(
|
706
|
-
root={UserProfile.user_id.name: FilterConditionsV0(eq=user_id)}
|
707
|
-
),
|
708
|
-
)["data"]["main"]
|
709
|
-
)
|
710
|
-
local_list_response_user_sessions = (
|
711
|
-
global_object_square_database_helper.get_rows_v0(
|
712
|
-
database_name=global_string_database_name,
|
713
|
-
schema_name=global_string_schema_name,
|
714
|
-
table_name=UserSession.__tablename__,
|
715
|
-
filters=FiltersV0(
|
716
|
-
root={
|
717
|
-
UserSession.user_id.name: FilterConditionsV0(eq=user_id),
|
718
|
-
UserSession.user_session_expiry_time.name: FilterConditionsV0(
|
719
|
-
gte=datetime.now(timezone.utc).isoformat()
|
720
|
-
),
|
721
|
-
}
|
722
|
-
),
|
723
|
-
)["data"]["main"]
|
724
|
-
)
|
725
|
-
user_profile = copy.deepcopy(local_list_response_user_profile[0])
|
726
|
-
del user_profile[UserProfile.user_id.name]
|
727
|
-
"""
|
728
|
-
return value
|
729
|
-
"""
|
730
|
-
return_this = {
|
731
|
-
"user_id": user_id,
|
732
|
-
"profile": user_profile,
|
733
|
-
"apps": [
|
734
|
-
y[App.app_name.name]
|
735
|
-
for y in local_list_app
|
736
|
-
if y[App.app_id.name]
|
737
|
-
in [x[UserApp.app_id.name] for x in local_list_response_user_app]
|
738
|
-
],
|
739
|
-
"sessions": [
|
740
|
-
{
|
741
|
-
"app_name": [
|
742
|
-
y[App.app_name.name]
|
743
|
-
for y in local_list_app
|
744
|
-
if y[App.app_id.name] == x[UserApp.app_id.name]
|
745
|
-
][0],
|
746
|
-
"active_sessions": len(
|
747
|
-
[
|
748
|
-
y
|
749
|
-
for y in local_list_response_user_sessions
|
750
|
-
if y[UserSession.app_id.name] == x[UserApp.app_id.name]
|
751
|
-
]
|
752
|
-
),
|
753
|
-
}
|
754
|
-
for x in local_list_response_user_app
|
755
|
-
],
|
756
|
-
}
|
757
|
-
output_content = get_api_output_in_standard_format(
|
758
|
-
message=messages["GENERIC_READ_SUCCESSFUL"],
|
759
|
-
data={"main": return_this},
|
760
|
-
)
|
761
|
-
return JSONResponse(
|
762
|
-
status_code=status.HTTP_200_OK,
|
763
|
-
content=output_content,
|
764
|
-
)
|
765
|
-
except HTTPException as http_exception:
|
766
|
-
global_object_square_logger.logger.error(http_exception, exc_info=True)
|
767
|
-
return JSONResponse(
|
768
|
-
status_code=http_exception.status_code, content=http_exception.detail
|
769
|
-
)
|
104
|
+
return util_get_user_details_v0(access_token=access_token)
|
105
|
+
except HTTPException as he:
|
106
|
+
global_object_square_logger.logger.error(he, exc_info=True)
|
107
|
+
return JSONResponse(status_code=he.status_code, content=he.detail)
|
770
108
|
except Exception as e:
|
771
|
-
"""
|
772
|
-
rollback logic
|
773
|
-
"""
|
774
109
|
global_object_square_logger.logger.error(e, exc_info=True)
|
775
110
|
output_content = get_api_output_in_standard_format(
|
776
|
-
message=messages["GENERIC_500"],
|
777
|
-
log=str(e),
|
111
|
+
message=messages["GENERIC_500"], log=str(e)
|
778
112
|
)
|
779
113
|
return JSONResponse(
|
780
|
-
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
781
|
-
content=output_content,
|
114
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
782
115
|
)
|
783
116
|
|
784
117
|
|
@@ -790,156 +123,21 @@ async def update_user_app_ids_v0(
|
|
790
123
|
app_ids_to_remove: List[int],
|
791
124
|
):
|
792
125
|
try:
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
)
|
802
|
-
except Exception as error:
|
803
|
-
output_content = get_api_output_in_standard_format(
|
804
|
-
message=messages["INCORRECT_ACCESS_TOKEN"], log=str(error)
|
805
|
-
)
|
806
|
-
raise HTTPException(
|
807
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
808
|
-
detail=output_content,
|
809
|
-
)
|
810
|
-
user_id = local_dict_access_token_payload["user_id"]
|
811
|
-
|
812
|
-
app_ids_to_add = list(set(app_ids_to_add))
|
813
|
-
app_ids_to_remove = list(set(app_ids_to_remove))
|
814
|
-
|
815
|
-
# check if app_ids_to_add and app_ids_to_remove don't have common ids.
|
816
|
-
local_list_common_app_ids = set(app_ids_to_add) & set(app_ids_to_remove)
|
817
|
-
if len(local_list_common_app_ids) > 0:
|
818
|
-
output_content = get_api_output_in_standard_format(
|
819
|
-
message=messages["GENERIC_400"],
|
820
|
-
log=f"invalid app_ids: {list(local_list_common_app_ids)}, present in both add list and remove list.",
|
821
|
-
)
|
822
|
-
raise HTTPException(
|
823
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
824
|
-
detail=output_content,
|
825
|
-
)
|
826
|
-
|
827
|
-
# check if all app_ids are valid
|
828
|
-
local_list_all_app_ids = [*app_ids_to_add, *app_ids_to_remove]
|
829
|
-
local_list_response_app = global_object_square_database_helper.get_rows_v0(
|
830
|
-
database_name=global_string_database_name,
|
831
|
-
schema_name=global_string_public_schema_name,
|
832
|
-
table_name=App.__tablename__,
|
833
|
-
apply_filters=False,
|
834
|
-
filters=FiltersV0(root={}),
|
835
|
-
)["data"]["main"]
|
836
|
-
local_list_invalid_ids = [
|
837
|
-
x
|
838
|
-
for x in local_list_all_app_ids
|
839
|
-
if x not in [y[App.app_id.name] for y in local_list_response_app]
|
840
|
-
]
|
841
|
-
if len(local_list_invalid_ids) > 0:
|
842
|
-
output_content = get_api_output_in_standard_format(
|
843
|
-
message=messages["GENERIC_400"],
|
844
|
-
log=f"invalid app_ids: {local_list_invalid_ids}.",
|
845
|
-
)
|
846
|
-
raise HTTPException(
|
847
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
848
|
-
detail=output_content,
|
849
|
-
)
|
850
|
-
"""
|
851
|
-
main process
|
852
|
-
"""
|
853
|
-
# logic for adding new app_ids
|
854
|
-
local_list_response_user_app = global_object_square_database_helper.get_rows_v0(
|
855
|
-
database_name=global_string_database_name,
|
856
|
-
schema_name=global_string_schema_name,
|
857
|
-
table_name=UserApp.__tablename__,
|
858
|
-
filters=FiltersV0(
|
859
|
-
root={UserApp.user_id.name: FilterConditionsV0(eq=user_id)}
|
860
|
-
),
|
861
|
-
)["data"]["main"]
|
862
|
-
local_list_new_app_ids = [
|
863
|
-
{
|
864
|
-
UserApp.user_id.name: user_id,
|
865
|
-
UserApp.app_id.name: x,
|
866
|
-
}
|
867
|
-
for x in app_ids_to_add
|
868
|
-
if x not in [y[UserApp.app_id.name] for y in local_list_response_user_app]
|
869
|
-
]
|
870
|
-
if len(local_list_new_app_ids) > 0:
|
871
|
-
global_object_square_database_helper.insert_rows_v0(
|
872
|
-
database_name=global_string_database_name,
|
873
|
-
schema_name=global_string_schema_name,
|
874
|
-
table_name=UserApp.__tablename__,
|
875
|
-
data=local_list_new_app_ids,
|
876
|
-
)
|
877
|
-
|
878
|
-
# logic for removing app_ids
|
879
|
-
for app_id in app_ids_to_remove:
|
880
|
-
global_object_square_database_helper.delete_rows_v0(
|
881
|
-
database_name=global_string_database_name,
|
882
|
-
schema_name=global_string_schema_name,
|
883
|
-
table_name=UserApp.__tablename__,
|
884
|
-
filters=FiltersV0(
|
885
|
-
root={
|
886
|
-
UserApp.user_id.name: FilterConditionsV0(eq=user_id),
|
887
|
-
UserApp.app_id.name: FilterConditionsV0(eq=app_id),
|
888
|
-
}
|
889
|
-
),
|
890
|
-
)
|
891
|
-
# logout user from removed apps
|
892
|
-
global_object_square_database_helper.delete_rows_v0(
|
893
|
-
database_name=global_string_database_name,
|
894
|
-
schema_name=global_string_schema_name,
|
895
|
-
table_name=UserSession.__tablename__,
|
896
|
-
filters=FiltersV0(
|
897
|
-
root={
|
898
|
-
UserSession.user_id.name: FilterConditionsV0(eq=user_id),
|
899
|
-
UserSession.app_id.name: FilterConditionsV0(eq=app_id),
|
900
|
-
}
|
901
|
-
),
|
902
|
-
)
|
903
|
-
|
904
|
-
"""
|
905
|
-
return value
|
906
|
-
"""
|
907
|
-
# get latest app ids
|
908
|
-
local_list_response_user_app = global_object_square_database_helper.get_rows_v0(
|
909
|
-
database_name=global_string_database_name,
|
910
|
-
schema_name=global_string_schema_name,
|
911
|
-
table_name=UserApp.__tablename__,
|
912
|
-
filters=FiltersV0(
|
913
|
-
root={UserApp.user_id.name: FilterConditionsV0(eq=user_id)}
|
914
|
-
),
|
915
|
-
)["data"]["main"]
|
916
|
-
output_content = get_api_output_in_standard_format(
|
917
|
-
message=messages["GENERIC_UPDATE_SUCCESSFUL"],
|
918
|
-
data={
|
919
|
-
"main": [x[UserApp.app_id.name] for x in local_list_response_user_app]
|
920
|
-
},
|
921
|
-
)
|
922
|
-
return JSONResponse(
|
923
|
-
status_code=status.HTTP_200_OK,
|
924
|
-
content=output_content,
|
925
|
-
)
|
926
|
-
except HTTPException as http_exception:
|
927
|
-
global_object_square_logger.logger.error(http_exception, exc_info=True)
|
928
|
-
return JSONResponse(
|
929
|
-
status_code=http_exception.status_code, content=http_exception.detail
|
930
|
-
)
|
126
|
+
return util_update_user_app_ids_v0(
|
127
|
+
access_token=access_token,
|
128
|
+
app_ids_to_add=app_ids_to_add,
|
129
|
+
app_ids_to_remove=app_ids_to_remove,
|
130
|
+
)
|
131
|
+
except HTTPException as he:
|
132
|
+
global_object_square_logger.logger.error(he, exc_info=True)
|
133
|
+
return JSONResponse(status_code=he.status_code, content=he.detail)
|
931
134
|
except Exception as e:
|
932
|
-
"""
|
933
|
-
rollback logic
|
934
|
-
"""
|
935
135
|
global_object_square_logger.logger.error(e, exc_info=True)
|
936
136
|
output_content = get_api_output_in_standard_format(
|
937
|
-
message=messages["GENERIC_500"],
|
938
|
-
log=str(e),
|
137
|
+
message=messages["GENERIC_500"], log=str(e)
|
939
138
|
)
|
940
139
|
return JSONResponse(
|
941
|
-
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
942
|
-
content=output_content,
|
140
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
943
141
|
)
|
944
142
|
|
945
143
|
|
@@ -952,221 +150,19 @@ async def login_username_v0(body: LoginUsernameV0):
|
|
952
150
|
assign_app_id_if_missing = body.assign_app_id_if_missing
|
953
151
|
username = username.lower()
|
954
152
|
try:
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
filters=FiltersV0(
|
965
|
-
root={User.user_username.name: FilterConditionsV0(eq=username)}
|
966
|
-
),
|
967
|
-
)["data"]["main"]
|
968
|
-
if len(local_list_response_user) != 1:
|
969
|
-
output_content = get_api_output_in_standard_format(
|
970
|
-
message=messages["INCORRECT_USERNAME"],
|
971
|
-
log=f"incorrect username {username}",
|
972
|
-
)
|
973
|
-
raise HTTPException(
|
974
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
975
|
-
detail=output_content,
|
976
|
-
)
|
977
|
-
# check if user has auth provider as SELF
|
978
|
-
local_list_user_auth_provider_response = (
|
979
|
-
global_object_square_database_helper.get_rows_v0(
|
980
|
-
database_name=global_string_database_name,
|
981
|
-
schema_name=global_string_schema_name,
|
982
|
-
table_name=UserAuthProvider.__tablename__,
|
983
|
-
filters=FiltersV0(
|
984
|
-
root={
|
985
|
-
UserAuthProvider.user_id.name: FilterConditionsV0(
|
986
|
-
eq=local_list_response_user[0][User.user_id.name]
|
987
|
-
),
|
988
|
-
UserAuthProvider.auth_provider.name: FilterConditionsV0(
|
989
|
-
eq=AuthProviderEnum.SELF.value
|
990
|
-
),
|
991
|
-
}
|
992
|
-
),
|
993
|
-
)["data"]["main"]
|
994
|
-
)
|
995
|
-
if len(local_list_user_auth_provider_response) != 1:
|
996
|
-
output_content = get_api_output_in_standard_format(
|
997
|
-
message=messages["INCORRECT_AUTH_PROVIDER"],
|
998
|
-
log=f"{username} not linked with {AuthProviderEnum.SELF.value} auth provider.",
|
999
|
-
)
|
1000
|
-
raise HTTPException(
|
1001
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
1002
|
-
detail=output_content,
|
1003
|
-
)
|
1004
|
-
# check if user has credentials (might not be set in case of errors in registration.)
|
1005
|
-
local_list_authentication_user_response = (
|
1006
|
-
global_object_square_database_helper.get_rows_v0(
|
1007
|
-
database_name=global_string_database_name,
|
1008
|
-
schema_name=global_string_schema_name,
|
1009
|
-
table_name=UserCredential.__tablename__,
|
1010
|
-
filters=FiltersV0(
|
1011
|
-
root={
|
1012
|
-
UserCredential.user_id.name: FilterConditionsV0(
|
1013
|
-
eq=local_list_response_user[0][User.user_id.name]
|
1014
|
-
)
|
1015
|
-
}
|
1016
|
-
),
|
1017
|
-
)["data"]["main"]
|
1018
|
-
)
|
1019
|
-
if len(local_list_authentication_user_response) != 1:
|
1020
|
-
output_content = get_api_output_in_standard_format(
|
1021
|
-
message=messages["MALFORMED_USER"],
|
1022
|
-
log=f"username: {username} does not have credentials set.",
|
1023
|
-
)
|
1024
|
-
raise HTTPException(
|
1025
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
1026
|
-
detail=output_content,
|
1027
|
-
)
|
1028
|
-
# validate if app_id is assigned to user
|
1029
|
-
# this will also validate if app_id is valid
|
1030
|
-
local_dict_user = local_list_authentication_user_response[0]
|
1031
|
-
local_str_user_id = local_dict_user[UserCredential.user_id.name]
|
1032
|
-
local_list_user_app_response = global_object_square_database_helper.get_rows_v0(
|
1033
|
-
database_name=global_string_database_name,
|
1034
|
-
schema_name=global_string_schema_name,
|
1035
|
-
table_name=UserApp.__tablename__,
|
1036
|
-
filters=FiltersV0(
|
1037
|
-
root={
|
1038
|
-
UserApp.user_id.name: FilterConditionsV0(eq=local_str_user_id),
|
1039
|
-
UserApp.app_id.name: FilterConditionsV0(eq=app_id),
|
1040
|
-
}
|
1041
|
-
),
|
1042
|
-
)["data"]["main"]
|
1043
|
-
if len(local_list_user_app_response) == 0:
|
1044
|
-
if assign_app_id_if_missing:
|
1045
|
-
try:
|
1046
|
-
global_object_square_database_helper.insert_rows_v0(
|
1047
|
-
database_name=global_string_database_name,
|
1048
|
-
schema_name=global_string_schema_name,
|
1049
|
-
table_name=UserApp.__tablename__,
|
1050
|
-
data=[
|
1051
|
-
{
|
1052
|
-
UserApp.user_id.name: local_str_user_id,
|
1053
|
-
UserApp.app_id.name: app_id,
|
1054
|
-
}
|
1055
|
-
],
|
1056
|
-
)
|
1057
|
-
except HTTPError as he:
|
1058
|
-
output_content = get_api_output_in_standard_format(
|
1059
|
-
message=messages["GENERIC_400"],
|
1060
|
-
log=str(he),
|
1061
|
-
)
|
1062
|
-
raise HTTPException(
|
1063
|
-
status_code=he.response.status_code, detail=output_content
|
1064
|
-
)
|
1065
|
-
else:
|
1066
|
-
output_content = get_api_output_in_standard_format(
|
1067
|
-
message=messages["GENERIC_400"],
|
1068
|
-
log=f"user_id {local_str_user_id}({username}) not assigned to app {app_id}.",
|
1069
|
-
)
|
1070
|
-
raise HTTPException(
|
1071
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
1072
|
-
detail=output_content,
|
1073
|
-
)
|
1074
|
-
|
1075
|
-
# validate password
|
1076
|
-
if not (
|
1077
|
-
bcrypt.checkpw(
|
1078
|
-
password.encode("utf-8"),
|
1079
|
-
local_dict_user[
|
1080
|
-
UserCredential.user_credential_hashed_password.name
|
1081
|
-
].encode("utf-8"),
|
1082
|
-
)
|
1083
|
-
):
|
1084
|
-
output_content = get_api_output_in_standard_format(
|
1085
|
-
message=messages["INCORRECT_PASSWORD"],
|
1086
|
-
log=f"incorrect password for user_id {local_str_user_id}({username}).",
|
1087
|
-
)
|
1088
|
-
raise HTTPException(
|
1089
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
1090
|
-
detail=output_content,
|
1091
|
-
)
|
1092
|
-
"""
|
1093
|
-
main process
|
1094
|
-
"""
|
1095
|
-
# return new access token and refresh token
|
1096
|
-
|
1097
|
-
# create access token
|
1098
|
-
local_dict_access_token_payload = {
|
1099
|
-
"app_id": app_id,
|
1100
|
-
"user_id": local_str_user_id,
|
1101
|
-
"exp": datetime.now(timezone.utc)
|
1102
|
-
+ timedelta(minutes=config_int_access_token_valid_minutes),
|
1103
|
-
}
|
1104
|
-
local_str_access_token = jwt.encode(
|
1105
|
-
local_dict_access_token_payload,
|
1106
|
-
config_str_secret_key_for_access_token,
|
1107
|
-
)
|
1108
|
-
|
1109
|
-
# create refresh token
|
1110
|
-
local_object_refresh_token_expiry_time = datetime.now(timezone.utc) + timedelta(
|
1111
|
-
minutes=config_int_refresh_token_valid_minutes
|
1112
|
-
)
|
1113
|
-
|
1114
|
-
local_dict_refresh_token_payload = {
|
1115
|
-
"app_id": app_id,
|
1116
|
-
"user_id": local_str_user_id,
|
1117
|
-
"exp": local_object_refresh_token_expiry_time,
|
1118
|
-
}
|
1119
|
-
local_str_refresh_token = jwt.encode(
|
1120
|
-
local_dict_refresh_token_payload,
|
1121
|
-
config_str_secret_key_for_refresh_token,
|
1122
|
-
)
|
1123
|
-
# entry in user session table
|
1124
|
-
global_object_square_database_helper.insert_rows_v0(
|
1125
|
-
data=[
|
1126
|
-
{
|
1127
|
-
UserSession.user_id.name: local_str_user_id,
|
1128
|
-
UserSession.app_id.name: app_id,
|
1129
|
-
UserSession.user_session_refresh_token.name: local_str_refresh_token,
|
1130
|
-
UserSession.user_session_expiry_time.name: local_object_refresh_token_expiry_time.strftime(
|
1131
|
-
"%Y-%m-%d %H:%M:%S.%f+00"
|
1132
|
-
),
|
1133
|
-
}
|
1134
|
-
],
|
1135
|
-
database_name=global_string_database_name,
|
1136
|
-
schema_name=global_string_schema_name,
|
1137
|
-
table_name=UserSession.__tablename__,
|
1138
|
-
)
|
1139
|
-
"""
|
1140
|
-
return value
|
1141
|
-
"""
|
1142
|
-
output_content = get_api_output_in_standard_format(
|
1143
|
-
data={
|
1144
|
-
"main": {
|
1145
|
-
"user_id": local_str_user_id,
|
1146
|
-
"access_token": local_str_access_token,
|
1147
|
-
"refresh_token": local_str_refresh_token,
|
1148
|
-
"refresh_token_expiry_time": local_object_refresh_token_expiry_time.isoformat(),
|
1149
|
-
}
|
1150
|
-
},
|
1151
|
-
message=messages["LOGIN_SUCCESSFUL"],
|
1152
|
-
)
|
1153
|
-
return JSONResponse(
|
1154
|
-
status_code=status.HTTP_200_OK,
|
1155
|
-
content=output_content,
|
1156
|
-
)
|
1157
|
-
except HTTPException as http_exception:
|
1158
|
-
global_object_square_logger.logger.error(http_exception, exc_info=True)
|
1159
|
-
return JSONResponse(
|
1160
|
-
status_code=http_exception.status_code, content=http_exception.detail
|
1161
|
-
)
|
153
|
+
return util_login_username_v0(
|
154
|
+
username=username,
|
155
|
+
password=password,
|
156
|
+
app_id=app_id,
|
157
|
+
assign_app_id_if_missing=assign_app_id_if_missing,
|
158
|
+
)
|
159
|
+
except HTTPException as he:
|
160
|
+
global_object_square_logger.logger.error(he, exc_info=True)
|
161
|
+
return JSONResponse(status_code=he.status_code, content=he.detail)
|
1162
162
|
except Exception as e:
|
1163
|
-
"""
|
1164
|
-
rollback logic
|
1165
|
-
"""
|
1166
163
|
global_object_square_logger.logger.error(e, exc_info=True)
|
1167
164
|
output_content = get_api_output_in_standard_format(
|
1168
|
-
message=messages["GENERIC_500"],
|
1169
|
-
log=str(e),
|
165
|
+
message=messages["GENERIC_500"], log=str(e)
|
1170
166
|
)
|
1171
167
|
return JSONResponse(
|
1172
168
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
@@ -1179,85 +175,16 @@ async def generate_access_token_v0(
|
|
1179
175
|
refresh_token: Annotated[str, Header()],
|
1180
176
|
):
|
1181
177
|
try:
|
1182
|
-
|
1183
|
-
|
1184
|
-
"""
|
1185
|
-
# validate refresh token
|
1186
|
-
# validating if a session refresh token exists in the database.
|
1187
|
-
local_list_user_session_response = (
|
1188
|
-
global_object_square_database_helper.get_rows_v0(
|
1189
|
-
database_name=global_string_database_name,
|
1190
|
-
schema_name=global_string_schema_name,
|
1191
|
-
table_name=UserSession.__tablename__,
|
1192
|
-
filters=FiltersV0(
|
1193
|
-
root={
|
1194
|
-
UserSession.user_session_refresh_token.name: FilterConditionsV0(
|
1195
|
-
eq=refresh_token
|
1196
|
-
),
|
1197
|
-
}
|
1198
|
-
),
|
1199
|
-
)["data"]["main"]
|
1200
|
-
)
|
1201
|
-
|
1202
|
-
if len(local_list_user_session_response) != 1:
|
1203
|
-
output_content = get_api_output_in_standard_format(
|
1204
|
-
message=messages["INCORRECT_REFRESH_TOKEN"],
|
1205
|
-
log=f"incorrect refresh token: {refresh_token}.",
|
1206
|
-
)
|
1207
|
-
raise HTTPException(
|
1208
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
1209
|
-
detail=output_content,
|
1210
|
-
)
|
1211
|
-
# validating if the refresh token is valid, active and of the same user.
|
1212
|
-
try:
|
1213
|
-
local_dict_refresh_token_payload = get_jwt_payload(
|
1214
|
-
refresh_token, config_str_secret_key_for_refresh_token
|
1215
|
-
)
|
1216
|
-
except Exception as error:
|
1217
|
-
output_content = get_api_output_in_standard_format(
|
1218
|
-
message=messages["INCORRECT_REFRESH_TOKEN"], log=str(error)
|
1219
|
-
)
|
1220
|
-
raise HTTPException(
|
1221
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
1222
|
-
detail=output_content,
|
1223
|
-
)
|
1224
|
-
"""
|
1225
|
-
main process
|
1226
|
-
"""
|
1227
|
-
# create and send access token
|
1228
|
-
local_dict_access_token_payload = {
|
1229
|
-
"app_id": local_dict_refresh_token_payload["app_id"],
|
1230
|
-
"user_id": local_dict_refresh_token_payload["user_id"],
|
1231
|
-
"exp": datetime.now(timezone.utc)
|
1232
|
-
+ timedelta(minutes=config_int_access_token_valid_minutes),
|
1233
|
-
}
|
1234
|
-
local_str_access_token = jwt.encode(
|
1235
|
-
local_dict_access_token_payload, config_str_secret_key_for_access_token
|
1236
|
-
)
|
1237
|
-
"""
|
1238
|
-
return value
|
1239
|
-
"""
|
1240
|
-
output_content = get_api_output_in_standard_format(
|
1241
|
-
data={"main": {"access_token": local_str_access_token}},
|
1242
|
-
message=messages["GENERIC_CREATION_SUCCESSFUL"],
|
1243
|
-
)
|
1244
|
-
return JSONResponse(
|
1245
|
-
status_code=status.HTTP_200_OK,
|
1246
|
-
content=output_content,
|
1247
|
-
)
|
1248
|
-
except HTTPException as http_exception:
|
1249
|
-
global_object_square_logger.logger.error(http_exception, exc_info=True)
|
1250
|
-
return JSONResponse(
|
1251
|
-
status_code=http_exception.status_code, content=http_exception.detail
|
178
|
+
return util_generate_access_token_v0(
|
179
|
+
refresh_token=refresh_token,
|
1252
180
|
)
|
181
|
+
except HTTPException as he:
|
182
|
+
global_object_square_logger.logger.error(he, exc_info=True)
|
183
|
+
return JSONResponse(status_code=he.status_code, content=he.detail)
|
1253
184
|
except Exception as e:
|
1254
|
-
"""
|
1255
|
-
rollback logic
|
1256
|
-
"""
|
1257
185
|
global_object_square_logger.logger.error(e, exc_info=True)
|
1258
186
|
output_content = get_api_output_in_standard_format(
|
1259
|
-
message=messages["GENERIC_500"],
|
1260
|
-
log=str(e),
|
187
|
+
message=messages["GENERIC_500"], log=str(e)
|
1261
188
|
)
|
1262
189
|
return JSONResponse(
|
1263
190
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
@@ -1270,86 +197,16 @@ async def logout_v0(
|
|
1270
197
|
refresh_token: Annotated[str, Header()],
|
1271
198
|
):
|
1272
199
|
try:
|
1273
|
-
|
1274
|
-
|
1275
|
-
"""
|
1276
|
-
# validate refresh token
|
1277
|
-
# validating if a session refresh token exists in the database.
|
1278
|
-
local_list_user_session_response = (
|
1279
|
-
global_object_square_database_helper.get_rows_v0(
|
1280
|
-
database_name=global_string_database_name,
|
1281
|
-
schema_name=global_string_schema_name,
|
1282
|
-
table_name=UserSession.__tablename__,
|
1283
|
-
filters=FiltersV0(
|
1284
|
-
root={
|
1285
|
-
UserSession.user_session_refresh_token.name: FilterConditionsV0(
|
1286
|
-
eq=refresh_token
|
1287
|
-
),
|
1288
|
-
}
|
1289
|
-
),
|
1290
|
-
)["data"]["main"]
|
1291
|
-
)
|
1292
|
-
|
1293
|
-
if len(local_list_user_session_response) != 1:
|
1294
|
-
output_content = get_api_output_in_standard_format(
|
1295
|
-
message=messages["INCORRECT_REFRESH_TOKEN"],
|
1296
|
-
log=f"incorrect refresh token: {refresh_token}.",
|
1297
|
-
)
|
1298
|
-
raise HTTPException(
|
1299
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
1300
|
-
detail=output_content,
|
1301
|
-
)
|
1302
|
-
# validating if the refresh token is valid, active and of the same user.
|
1303
|
-
try:
|
1304
|
-
_ = get_jwt_payload(refresh_token, config_str_secret_key_for_refresh_token)
|
1305
|
-
except Exception as error:
|
1306
|
-
output_content = get_api_output_in_standard_format(
|
1307
|
-
message=messages["INCORRECT_REFRESH_TOKEN"],
|
1308
|
-
log=str(error),
|
1309
|
-
)
|
1310
|
-
raise HTTPException(
|
1311
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
1312
|
-
detail=output_content,
|
1313
|
-
)
|
1314
|
-
# ======================================================================================
|
1315
|
-
# NOTE: if refresh token has expired no need to delete it during this call
|
1316
|
-
# ======================================================================================
|
1317
|
-
"""
|
1318
|
-
main process
|
1319
|
-
"""
|
1320
|
-
# delete session for user
|
1321
|
-
global_object_square_database_helper.delete_rows_v0(
|
1322
|
-
database_name=global_string_database_name,
|
1323
|
-
schema_name=global_string_schema_name,
|
1324
|
-
table_name=UserSession.__tablename__,
|
1325
|
-
filters=FiltersV0(
|
1326
|
-
root={
|
1327
|
-
UserSession.user_session_refresh_token.name: FilterConditionsV0(
|
1328
|
-
eq=refresh_token
|
1329
|
-
),
|
1330
|
-
}
|
1331
|
-
),
|
1332
|
-
)
|
1333
|
-
"""
|
1334
|
-
return value
|
1335
|
-
"""
|
1336
|
-
output_content = get_api_output_in_standard_format(
|
1337
|
-
message=messages["LOGOUT_SUCCESSFUL"],
|
1338
|
-
)
|
1339
|
-
return JSONResponse(status_code=status.HTTP_200_OK, content=output_content)
|
1340
|
-
except HTTPException as http_exception:
|
1341
|
-
global_object_square_logger.logger.error(http_exception, exc_info=True)
|
1342
|
-
return JSONResponse(
|
1343
|
-
status_code=http_exception.status_code, content=http_exception.detail
|
200
|
+
return util_logout_v0(
|
201
|
+
refresh_token=refresh_token,
|
1344
202
|
)
|
203
|
+
except HTTPException as he:
|
204
|
+
global_object_square_logger.logger.error(he, exc_info=True)
|
205
|
+
return JSONResponse(status_code=he.status_code, content=he.detail)
|
1345
206
|
except Exception as e:
|
1346
|
-
"""
|
1347
|
-
rollback logic
|
1348
|
-
"""
|
1349
207
|
global_object_square_logger.logger.error(e, exc_info=True)
|
1350
208
|
output_content = get_api_output_in_standard_format(
|
1351
|
-
message=messages["GENERIC_500"],
|
1352
|
-
log=str(e),
|
209
|
+
message=messages["GENERIC_500"], log=str(e)
|
1353
210
|
)
|
1354
211
|
return JSONResponse(
|
1355
212
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
@@ -1364,85 +221,14 @@ async def logout_apps_v0(
|
|
1364
221
|
):
|
1365
222
|
app_ids = body.app_ids
|
1366
223
|
try:
|
1367
|
-
|
1368
|
-
|
1369
|
-
|
1370
|
-
|
1371
|
-
local_dict_access_token_payload = get_jwt_payload(
|
1372
|
-
access_token, config_str_secret_key_for_access_token
|
1373
|
-
)
|
1374
|
-
except Exception as error:
|
1375
|
-
output_content = get_api_output_in_standard_format(
|
1376
|
-
message=messages["INCORRECT_ACCESS_TOKEN"], log=str(error)
|
1377
|
-
)
|
1378
|
-
raise HTTPException(
|
1379
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
1380
|
-
detail=output_content,
|
1381
|
-
)
|
1382
|
-
user_id = local_dict_access_token_payload["user_id"]
|
1383
|
-
# validate app_ids
|
1384
|
-
app_ids = list(set(app_ids))
|
1385
|
-
local_list_response_user_app = global_object_square_database_helper.get_rows_v0(
|
1386
|
-
database_name=global_string_database_name,
|
1387
|
-
schema_name=global_string_schema_name,
|
1388
|
-
table_name=UserApp.__tablename__,
|
1389
|
-
filters=FiltersV0(
|
1390
|
-
root={
|
1391
|
-
UserApp.user_id.name: FilterConditionsV0(eq=user_id),
|
1392
|
-
}
|
1393
|
-
),
|
1394
|
-
columns=[UserApp.app_id.name],
|
1395
|
-
)["data"]["main"]
|
1396
|
-
local_list_user_app_ids = [
|
1397
|
-
x[UserApp.app_id.name] for x in local_list_response_user_app
|
1398
|
-
]
|
1399
|
-
local_list_invalid_app_ids = [
|
1400
|
-
x for x in app_ids if x not in local_list_user_app_ids
|
1401
|
-
]
|
1402
|
-
if len(local_list_invalid_app_ids) > 0:
|
1403
|
-
output_content = get_api_output_in_standard_format(
|
1404
|
-
message=messages["GENERIC_400"],
|
1405
|
-
log=f"invalid app_ids: {local_list_invalid_app_ids}.",
|
1406
|
-
)
|
1407
|
-
raise HTTPException(
|
1408
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
1409
|
-
detail=output_content,
|
1410
|
-
)
|
1411
|
-
"""
|
1412
|
-
main process
|
1413
|
-
"""
|
1414
|
-
# delete session for user
|
1415
|
-
global_object_square_database_helper.delete_rows_v0(
|
1416
|
-
database_name=global_string_database_name,
|
1417
|
-
schema_name=global_string_schema_name,
|
1418
|
-
table_name=UserSession.__tablename__,
|
1419
|
-
filters=FiltersV0(
|
1420
|
-
root={
|
1421
|
-
UserSession.user_id.name: FilterConditionsV0(eq=user_id),
|
1422
|
-
UserSession.app_id.name: FilterConditionsV0(in_=app_ids),
|
1423
|
-
}
|
1424
|
-
),
|
1425
|
-
)
|
1426
|
-
"""
|
1427
|
-
return value
|
1428
|
-
"""
|
1429
|
-
output_content = get_api_output_in_standard_format(
|
1430
|
-
message=messages["LOGOUT_SUCCESSFUL"],
|
1431
|
-
)
|
1432
|
-
return JSONResponse(status_code=status.HTTP_200_OK, content=output_content)
|
1433
|
-
except HTTPException as http_exception:
|
1434
|
-
global_object_square_logger.logger.error(http_exception, exc_info=True)
|
1435
|
-
return JSONResponse(
|
1436
|
-
status_code=http_exception.status_code, content=http_exception.detail
|
1437
|
-
)
|
224
|
+
return util_logout_apps_v0(access_token=access_token, app_ids=app_ids)
|
225
|
+
except HTTPException as he:
|
226
|
+
global_object_square_logger.logger.error(he, exc_info=True)
|
227
|
+
return JSONResponse(status_code=he.status_code, content=he.detail)
|
1438
228
|
except Exception as e:
|
1439
|
-
"""
|
1440
|
-
rollback logic
|
1441
|
-
"""
|
1442
229
|
global_object_square_logger.logger.error(e, exc_info=True)
|
1443
230
|
output_content = get_api_output_in_standard_format(
|
1444
|
-
message=messages["GENERIC_500"],
|
1445
|
-
log=str(e),
|
231
|
+
message=messages["GENERIC_500"], log=str(e)
|
1446
232
|
)
|
1447
233
|
return JSONResponse(
|
1448
234
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
@@ -1454,59 +240,15 @@ async def logout_apps_v0(
|
|
1454
240
|
async def logout_all_v0(
|
1455
241
|
access_token: Annotated[str, Header()],
|
1456
242
|
):
|
1457
|
-
|
1458
243
|
try:
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1462
|
-
|
1463
|
-
local_dict_access_token_payload = get_jwt_payload(
|
1464
|
-
access_token, config_str_secret_key_for_access_token
|
1465
|
-
)
|
1466
|
-
except Exception as error:
|
1467
|
-
output_content = get_api_output_in_standard_format(
|
1468
|
-
message=messages["INCORRECT_ACCESS_TOKEN"], log=str(error)
|
1469
|
-
)
|
1470
|
-
raise HTTPException(
|
1471
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
1472
|
-
detail=output_content,
|
1473
|
-
)
|
1474
|
-
user_id = local_dict_access_token_payload["user_id"]
|
1475
|
-
|
1476
|
-
"""
|
1477
|
-
main process
|
1478
|
-
"""
|
1479
|
-
# delete session for user
|
1480
|
-
global_object_square_database_helper.delete_rows_v0(
|
1481
|
-
database_name=global_string_database_name,
|
1482
|
-
schema_name=global_string_schema_name,
|
1483
|
-
table_name=UserSession.__tablename__,
|
1484
|
-
filters=FiltersV0(
|
1485
|
-
root={
|
1486
|
-
UserSession.user_id.name: FilterConditionsV0(eq=user_id),
|
1487
|
-
}
|
1488
|
-
),
|
1489
|
-
)
|
1490
|
-
"""
|
1491
|
-
return value
|
1492
|
-
"""
|
1493
|
-
output_content = get_api_output_in_standard_format(
|
1494
|
-
message=messages["LOGOUT_SUCCESSFUL"],
|
1495
|
-
)
|
1496
|
-
return JSONResponse(status_code=status.HTTP_200_OK, content=output_content)
|
1497
|
-
except HTTPException as http_exception:
|
1498
|
-
global_object_square_logger.logger.error(http_exception, exc_info=True)
|
1499
|
-
return JSONResponse(
|
1500
|
-
status_code=http_exception.status_code, content=http_exception.detail
|
1501
|
-
)
|
244
|
+
return util_logout_all_v0(access_token=access_token)
|
245
|
+
except HTTPException as he:
|
246
|
+
global_object_square_logger.logger.error(he, exc_info=True)
|
247
|
+
return JSONResponse(status_code=he.status_code, content=he.detail)
|
1502
248
|
except Exception as e:
|
1503
|
-
"""
|
1504
|
-
rollback logic
|
1505
|
-
"""
|
1506
249
|
global_object_square_logger.logger.error(e, exc_info=True)
|
1507
250
|
output_content = get_api_output_in_standard_format(
|
1508
|
-
message=messages["GENERIC_500"],
|
1509
|
-
log=str(e),
|
251
|
+
message=messages["GENERIC_500"], log=str(e)
|
1510
252
|
)
|
1511
253
|
return JSONResponse(
|
1512
254
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
@@ -1520,121 +262,17 @@ async def update_username_v0(
|
|
1520
262
|
access_token: Annotated[str, Header()],
|
1521
263
|
):
|
1522
264
|
try:
|
1523
|
-
|
1524
|
-
|
1525
|
-
"""
|
1526
|
-
# validate access token
|
1527
|
-
try:
|
1528
|
-
local_dict_access_token_payload = get_jwt_payload(
|
1529
|
-
access_token, config_str_secret_key_for_access_token
|
1530
|
-
)
|
1531
|
-
except Exception as error:
|
1532
|
-
output_content = get_api_output_in_standard_format(
|
1533
|
-
message=messages["INCORRECT_ACCESS_TOKEN"], log=str(error)
|
1534
|
-
)
|
1535
|
-
raise HTTPException(
|
1536
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
1537
|
-
detail=output_content,
|
1538
|
-
)
|
1539
|
-
user_id = local_dict_access_token_payload["user_id"]
|
1540
|
-
|
1541
|
-
# validation for username
|
1542
|
-
new_username = new_username.lower()
|
1543
|
-
username_pattern = re.compile(r"^[a-z0-9._-]{2,20}$")
|
1544
|
-
if not username_pattern.match(new_username):
|
1545
|
-
output_content = get_api_output_in_standard_format(
|
1546
|
-
message=messages["USERNAME_INVALID"],
|
1547
|
-
log=f"username '{new_username}' is invalid. it must start and end with a letter, "
|
1548
|
-
f"contain only lowercase letters, numbers, underscores, or hyphens, "
|
1549
|
-
f"and not have consecutive separators.",
|
1550
|
-
)
|
1551
|
-
raise HTTPException(
|
1552
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
1553
|
-
detail=output_content,
|
1554
|
-
)
|
1555
|
-
|
1556
|
-
# validate user_id
|
1557
|
-
local_list_user_response = global_object_square_database_helper.get_rows_v0(
|
1558
|
-
database_name=global_string_database_name,
|
1559
|
-
schema_name=global_string_schema_name,
|
1560
|
-
table_name=User.__tablename__,
|
1561
|
-
filters=FiltersV0(
|
1562
|
-
root={
|
1563
|
-
User.user_id.name: FilterConditionsV0(eq=user_id),
|
1564
|
-
}
|
1565
|
-
),
|
1566
|
-
)["data"]["main"]
|
1567
|
-
|
1568
|
-
if len(local_list_user_response) != 1:
|
1569
|
-
output_content = get_api_output_in_standard_format(
|
1570
|
-
message=messages["INCORRECT_USER_ID"],
|
1571
|
-
log=f"incorrect user_id: {user_id}.",
|
1572
|
-
)
|
1573
|
-
raise HTTPException(
|
1574
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
1575
|
-
detail=output_content,
|
1576
|
-
)
|
1577
|
-
|
1578
|
-
# validate new username
|
1579
|
-
local_list_user_credentials_response = (
|
1580
|
-
global_object_square_database_helper.get_rows_v0(
|
1581
|
-
database_name=global_string_database_name,
|
1582
|
-
schema_name=global_string_schema_name,
|
1583
|
-
table_name=User.__tablename__,
|
1584
|
-
filters=FiltersV0(
|
1585
|
-
root={
|
1586
|
-
User.user_username.name: FilterConditionsV0(eq=new_username),
|
1587
|
-
}
|
1588
|
-
),
|
1589
|
-
)["data"]["main"]
|
1590
|
-
)
|
1591
|
-
if len(local_list_user_credentials_response) != 0:
|
1592
|
-
output_content = get_api_output_in_standard_format(
|
1593
|
-
message=messages["USERNAME_ALREADY_EXISTS"],
|
1594
|
-
log=f"{new_username} is taken.",
|
1595
|
-
)
|
1596
|
-
raise HTTPException(
|
1597
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
1598
|
-
detail=output_content,
|
1599
|
-
)
|
1600
|
-
"""
|
1601
|
-
main process
|
1602
|
-
"""
|
1603
|
-
# edit the username
|
1604
|
-
global_object_square_database_helper.edit_rows_v0(
|
1605
|
-
database_name=global_string_database_name,
|
1606
|
-
schema_name=global_string_schema_name,
|
1607
|
-
table_name=User.__tablename__,
|
1608
|
-
filters=FiltersV0(
|
1609
|
-
root={
|
1610
|
-
User.user_id.name: FilterConditionsV0(eq=user_id),
|
1611
|
-
}
|
1612
|
-
),
|
1613
|
-
data={
|
1614
|
-
User.user_username.name: new_username,
|
1615
|
-
},
|
1616
|
-
)
|
1617
|
-
"""
|
1618
|
-
return value
|
1619
|
-
"""
|
1620
|
-
output_content = get_api_output_in_standard_format(
|
1621
|
-
data={"main": {"user_id": user_id, "username": new_username}},
|
1622
|
-
message=messages["GENERIC_UPDATE_SUCCESSFUL"],
|
1623
|
-
)
|
1624
|
-
return JSONResponse(status_code=status.HTTP_200_OK, content=output_content)
|
1625
|
-
except HTTPException as http_exception:
|
1626
|
-
global_object_square_logger.logger.error(http_exception, exc_info=True)
|
1627
|
-
return JSONResponse(
|
1628
|
-
status_code=http_exception.status_code, content=http_exception.detail
|
265
|
+
return util_update_username_v0(
|
266
|
+
new_username=new_username, access_token=access_token
|
1629
267
|
)
|
268
|
+
|
269
|
+
except HTTPException as he:
|
270
|
+
global_object_square_logger.logger.error(he, exc_info=True)
|
271
|
+
return JSONResponse(status_code=he.status_code, content=he.detail)
|
1630
272
|
except Exception as e:
|
1631
|
-
"""
|
1632
|
-
rollback logic
|
1633
|
-
"""
|
1634
273
|
global_object_square_logger.logger.error(e, exc_info=True)
|
1635
274
|
output_content = get_api_output_in_standard_format(
|
1636
|
-
message=messages["GENERIC_500"],
|
1637
|
-
log=str(e),
|
275
|
+
message=messages["GENERIC_500"], log=str(e)
|
1638
276
|
)
|
1639
277
|
return JSONResponse(
|
1640
278
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
@@ -1649,121 +287,17 @@ async def delete_user_v0(
|
|
1649
287
|
):
|
1650
288
|
password = body.password
|
1651
289
|
try:
|
1652
|
-
|
1653
|
-
|
1654
|
-
|
1655
|
-
# validate access token
|
1656
|
-
try:
|
1657
|
-
local_dict_access_token_payload = get_jwt_payload(
|
1658
|
-
access_token, config_str_secret_key_for_access_token
|
1659
|
-
)
|
1660
|
-
except Exception as error:
|
1661
|
-
output_content = get_api_output_in_standard_format(
|
1662
|
-
message=messages["INCORRECT_ACCESS_TOKEN"], log=str(error)
|
1663
|
-
)
|
1664
|
-
raise HTTPException(
|
1665
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
1666
|
-
detail=output_content,
|
1667
|
-
)
|
1668
|
-
user_id = local_dict_access_token_payload["user_id"]
|
1669
|
-
|
1670
|
-
# validate user_id
|
1671
|
-
local_list_authentication_user_response = (
|
1672
|
-
global_object_square_database_helper.get_rows_v0(
|
1673
|
-
database_name=global_string_database_name,
|
1674
|
-
schema_name=global_string_schema_name,
|
1675
|
-
table_name=UserCredential.__tablename__,
|
1676
|
-
filters=FiltersV0(
|
1677
|
-
root={UserCredential.user_id.name: FilterConditionsV0(eq=user_id)}
|
1678
|
-
),
|
1679
|
-
)["data"]["main"]
|
1680
|
-
)
|
1681
|
-
if len(local_list_authentication_user_response) != 1:
|
1682
|
-
output_content = get_api_output_in_standard_format(
|
1683
|
-
message=messages["INCORRECT_USER_ID"],
|
1684
|
-
log=f"incorrect user_id: {user_id}.",
|
1685
|
-
)
|
1686
|
-
raise HTTPException(
|
1687
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
1688
|
-
detail=output_content,
|
1689
|
-
)
|
1690
|
-
|
1691
|
-
# validate password
|
1692
|
-
local_dict_user = local_list_authentication_user_response[0]
|
1693
|
-
if not (
|
1694
|
-
bcrypt.checkpw(
|
1695
|
-
password.encode("utf-8"),
|
1696
|
-
local_dict_user[
|
1697
|
-
UserCredential.user_credential_hashed_password.name
|
1698
|
-
].encode("utf-8"),
|
1699
|
-
)
|
1700
|
-
):
|
1701
|
-
output_content = get_api_output_in_standard_format(
|
1702
|
-
message=messages["INCORRECT_PASSWORD"],
|
1703
|
-
log=f"incorrect password for user_id {user_id}.",
|
1704
|
-
)
|
1705
|
-
raise HTTPException(
|
1706
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
1707
|
-
detail=output_content,
|
1708
|
-
)
|
1709
|
-
"""
|
1710
|
-
main process
|
1711
|
-
"""
|
1712
|
-
# fetch user profile photo storage token
|
1713
|
-
user_profile_storage_token = global_object_square_database_helper.get_rows_v0(
|
1714
|
-
database_name=global_string_database_name,
|
1715
|
-
schema_name=global_string_schema_name,
|
1716
|
-
table_name=UserProfile.__tablename__,
|
1717
|
-
filters=FiltersV0(
|
1718
|
-
root={UserProfile.user_id.name: FilterConditionsV0(eq=user_id)}
|
1719
|
-
),
|
1720
|
-
columns=[UserProfile.user_profile_photo_storage_token.name],
|
1721
|
-
)["data"]["main"][0][UserProfile.user_profile_photo_storage_token.name]
|
1722
|
-
|
1723
|
-
# delete the user.
|
1724
|
-
global_object_square_database_helper.delete_rows_v0(
|
1725
|
-
database_name=global_string_database_name,
|
1726
|
-
schema_name=global_string_schema_name,
|
1727
|
-
table_name=User.__tablename__,
|
1728
|
-
filters=FiltersV0(
|
1729
|
-
root={
|
1730
|
-
User.user_id.name: FilterConditionsV0(eq=user_id),
|
1731
|
-
}
|
1732
|
-
),
|
1733
|
-
)
|
1734
|
-
# delete profile photo if exists
|
1735
|
-
if user_profile_storage_token:
|
1736
|
-
try:
|
1737
|
-
global_object_square_file_store_helper.delete_file_v0(
|
1738
|
-
list_file_storage_token=[user_profile_storage_token]
|
1739
|
-
)
|
1740
|
-
except HTTPError as he:
|
1741
|
-
global_object_square_logger.warning(
|
1742
|
-
f"Failed to delete user profile photo with storage token {user_profile_storage_token}. "
|
1743
|
-
f"Error: {he.response.text}",
|
1744
|
-
exc_info=True,
|
1745
|
-
)
|
1746
|
-
"""
|
1747
|
-
return value
|
1748
|
-
"""
|
1749
|
-
output_content = get_api_output_in_standard_format(
|
1750
|
-
message=messages["GENERIC_DELETE_SUCCESSFUL"],
|
1751
|
-
log=f"user_id: {user_id} deleted successfully.",
|
1752
|
-
)
|
1753
|
-
return JSONResponse(status_code=status.HTTP_200_OK, content=output_content)
|
1754
|
-
except HTTPException as http_exception:
|
1755
|
-
global_object_square_logger.logger.error(http_exception, exc_info=True)
|
1756
|
-
return JSONResponse(
|
1757
|
-
status_code=http_exception.status_code, content=http_exception.detail
|
290
|
+
return util_delete_user_v0(
|
291
|
+
password=password,
|
292
|
+
access_token=access_token,
|
1758
293
|
)
|
294
|
+
except HTTPException as he:
|
295
|
+
global_object_square_logger.logger.error(he, exc_info=True)
|
296
|
+
return JSONResponse(status_code=he.status_code, content=he.detail)
|
1759
297
|
except Exception as e:
|
1760
|
-
"""
|
1761
|
-
rollback logic
|
1762
|
-
"""
|
1763
298
|
global_object_square_logger.logger.error(e, exc_info=True)
|
1764
299
|
output_content = get_api_output_in_standard_format(
|
1765
|
-
message=messages["GENERIC_500"],
|
1766
|
-
log=str(e),
|
300
|
+
message=messages["GENERIC_500"], log=str(e)
|
1767
301
|
)
|
1768
302
|
return JSONResponse(
|
1769
303
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
@@ -1781,203 +315,20 @@ async def update_password_v0(
|
|
1781
315
|
logout_other_sessions = body.logout_other_sessions
|
1782
316
|
preserve_session_refresh_token = body.preserve_session_refresh_token
|
1783
317
|
try:
|
1784
|
-
|
1785
|
-
|
1786
|
-
|
1787
|
-
|
1788
|
-
|
1789
|
-
|
1790
|
-
|
1791
|
-
|
1792
|
-
|
1793
|
-
|
1794
|
-
message=messages["INCORRECT_ACCESS_TOKEN"], log=str(error)
|
1795
|
-
)
|
1796
|
-
raise HTTPException(
|
1797
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
1798
|
-
detail=output_content,
|
1799
|
-
)
|
1800
|
-
user_id = local_dict_access_token_payload["user_id"]
|
1801
|
-
|
1802
|
-
# validate user_id
|
1803
|
-
local_list_authentication_user_response = (
|
1804
|
-
global_object_square_database_helper.get_rows_v0(
|
1805
|
-
database_name=global_string_database_name,
|
1806
|
-
schema_name=global_string_schema_name,
|
1807
|
-
table_name=UserCredential.__tablename__,
|
1808
|
-
filters=FiltersV0(
|
1809
|
-
root={UserCredential.user_id.name: FilterConditionsV0(eq=user_id)}
|
1810
|
-
),
|
1811
|
-
)["data"]["main"]
|
1812
|
-
)
|
1813
|
-
if len(local_list_authentication_user_response) != 1:
|
1814
|
-
output_content = get_api_output_in_standard_format(
|
1815
|
-
message=messages["INCORRECT_USER_ID"],
|
1816
|
-
log=f"incorrect user_id: {user_id}.",
|
1817
|
-
)
|
1818
|
-
raise HTTPException(
|
1819
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
1820
|
-
detail=output_content,
|
1821
|
-
)
|
1822
|
-
# check if user has SELF auth provider
|
1823
|
-
local_list_response_user_auth_provider = (
|
1824
|
-
global_object_square_database_helper.get_rows_v0(
|
1825
|
-
database_name=global_string_database_name,
|
1826
|
-
schema_name=global_string_schema_name,
|
1827
|
-
table_name=UserAuthProvider.__tablename__,
|
1828
|
-
filters=FiltersV0(
|
1829
|
-
root={
|
1830
|
-
UserAuthProvider.user_id.name: FilterConditionsV0(eq=user_id),
|
1831
|
-
UserAuthProvider.auth_provider.name: FilterConditionsV0(
|
1832
|
-
eq=AuthProviderEnum.SELF.value
|
1833
|
-
),
|
1834
|
-
}
|
1835
|
-
),
|
1836
|
-
)["data"]["main"]
|
1837
|
-
)
|
1838
|
-
if len(local_list_response_user_auth_provider) != 1:
|
1839
|
-
output_content = get_api_output_in_standard_format(
|
1840
|
-
message=messages["INCORRECT_AUTH_PROVIDER"],
|
1841
|
-
log=f"user_id: {user_id} does not have {AuthProviderEnum.SELF.value} auth provider.",
|
1842
|
-
)
|
1843
|
-
raise HTTPException(
|
1844
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
1845
|
-
detail=output_content,
|
1846
|
-
)
|
1847
|
-
# check if user has credentials (might not be set in case of errors in registration.)
|
1848
|
-
local_list_response_user = global_object_square_database_helper.get_rows_v0(
|
1849
|
-
database_name=global_string_database_name,
|
1850
|
-
schema_name=global_string_schema_name,
|
1851
|
-
table_name=User.__tablename__,
|
1852
|
-
filters=FiltersV0(root={User.user_id.name: FilterConditionsV0(eq=user_id)}),
|
1853
|
-
)["data"]["main"]
|
1854
|
-
if len(local_list_response_user) != 1:
|
1855
|
-
output_content = get_api_output_in_standard_format(
|
1856
|
-
message=messages["MALFORMED_USER"],
|
1857
|
-
log=f"user_id: {user_id} does not have credentials.",
|
1858
|
-
)
|
1859
|
-
raise HTTPException(
|
1860
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
1861
|
-
detail=output_content,
|
1862
|
-
)
|
1863
|
-
# validate password
|
1864
|
-
local_dict_user = local_list_authentication_user_response[0]
|
1865
|
-
if not (
|
1866
|
-
bcrypt.checkpw(
|
1867
|
-
old_password.encode("utf-8"),
|
1868
|
-
local_dict_user[
|
1869
|
-
UserCredential.user_credential_hashed_password.name
|
1870
|
-
].encode("utf-8"),
|
1871
|
-
)
|
1872
|
-
):
|
1873
|
-
output_content = get_api_output_in_standard_format(
|
1874
|
-
message=messages["INCORRECT_PASSWORD"],
|
1875
|
-
log=f"incorrect password for user_id {user_id}.",
|
1876
|
-
)
|
1877
|
-
raise HTTPException(
|
1878
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
1879
|
-
detail=output_content,
|
1880
|
-
)
|
1881
|
-
# check if provided refresh token is valid
|
1882
|
-
if preserve_session_refresh_token:
|
1883
|
-
local_dict_token_payload = get_jwt_payload(
|
1884
|
-
preserve_session_refresh_token, config_str_secret_key_for_refresh_token
|
1885
|
-
)
|
1886
|
-
local_list_response_user_session = global_object_square_database_helper.get_rows_v0(
|
1887
|
-
database_name=global_string_database_name,
|
1888
|
-
schema_name=global_string_schema_name,
|
1889
|
-
table_name=UserSession.__tablename__,
|
1890
|
-
filters=FiltersV0(
|
1891
|
-
root={
|
1892
|
-
UserSession.user_id.name: FilterConditionsV0(eq=user_id),
|
1893
|
-
UserSession.user_session_refresh_token.name: FilterConditionsV0(
|
1894
|
-
eq=preserve_session_refresh_token
|
1895
|
-
),
|
1896
|
-
}
|
1897
|
-
),
|
1898
|
-
)[
|
1899
|
-
"data"
|
1900
|
-
][
|
1901
|
-
"main"
|
1902
|
-
]
|
1903
|
-
if len(local_list_response_user_session) != 1:
|
1904
|
-
output_content = get_api_output_in_standard_format(
|
1905
|
-
message=messages["INCORRECT_REFRESH_TOKEN"],
|
1906
|
-
log=f"incorrect refresh token: {preserve_session_refresh_token}.",
|
1907
|
-
)
|
1908
|
-
raise HTTPException(
|
1909
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
1910
|
-
detail=output_content,
|
1911
|
-
)
|
1912
|
-
"""
|
1913
|
-
main process
|
1914
|
-
"""
|
1915
|
-
# update the password
|
1916
|
-
local_str_hashed_password = bcrypt.hashpw(
|
1917
|
-
new_password.encode("utf-8"), bcrypt.gensalt()
|
1918
|
-
).decode("utf-8")
|
1919
|
-
global_object_square_database_helper.edit_rows_v0(
|
1920
|
-
database_name=global_string_database_name,
|
1921
|
-
schema_name=global_string_schema_name,
|
1922
|
-
table_name=UserCredential.__tablename__,
|
1923
|
-
filters=FiltersV0(
|
1924
|
-
root={
|
1925
|
-
UserCredential.user_id.name: FilterConditionsV0(eq=user_id),
|
1926
|
-
}
|
1927
|
-
),
|
1928
|
-
data={
|
1929
|
-
UserCredential.user_credential_hashed_password.name: local_str_hashed_password,
|
1930
|
-
},
|
1931
|
-
)
|
1932
|
-
if logout_other_sessions:
|
1933
|
-
if preserve_session_refresh_token:
|
1934
|
-
# delete all sessions for user except the one with the given refresh token
|
1935
|
-
global_object_square_database_helper.delete_rows_v0(
|
1936
|
-
database_name=global_string_database_name,
|
1937
|
-
schema_name=global_string_schema_name,
|
1938
|
-
table_name=UserSession.__tablename__,
|
1939
|
-
filters=FiltersV0(
|
1940
|
-
root={
|
1941
|
-
UserSession.user_id.name: FilterConditionsV0(eq=user_id),
|
1942
|
-
UserSession.user_session_refresh_token.name: FilterConditionsV0(
|
1943
|
-
ne=preserve_session_refresh_token
|
1944
|
-
),
|
1945
|
-
}
|
1946
|
-
),
|
1947
|
-
)
|
1948
|
-
else:
|
1949
|
-
# delete all sessions for user
|
1950
|
-
global_object_square_database_helper.delete_rows_v0(
|
1951
|
-
database_name=global_string_database_name,
|
1952
|
-
schema_name=global_string_schema_name,
|
1953
|
-
table_name=UserSession.__tablename__,
|
1954
|
-
filters=FiltersV0(
|
1955
|
-
root={
|
1956
|
-
UserSession.user_id.name: FilterConditionsV0(eq=user_id),
|
1957
|
-
}
|
1958
|
-
),
|
1959
|
-
)
|
1960
|
-
"""
|
1961
|
-
return value
|
1962
|
-
"""
|
1963
|
-
output_content = get_api_output_in_standard_format(
|
1964
|
-
message=messages["GENERIC_UPDATE_SUCCESSFUL"],
|
1965
|
-
log=f"password for user_id: {user_id} updated successfully.",
|
1966
|
-
)
|
1967
|
-
return JSONResponse(status_code=status.HTTP_200_OK, content=output_content)
|
1968
|
-
except HTTPException as http_exception:
|
1969
|
-
global_object_square_logger.logger.error(http_exception, exc_info=True)
|
1970
|
-
return JSONResponse(
|
1971
|
-
status_code=http_exception.status_code, content=http_exception.detail
|
1972
|
-
)
|
318
|
+
return util_update_password_v0(
|
319
|
+
old_password=old_password,
|
320
|
+
new_password=new_password,
|
321
|
+
logout_other_sessions=logout_other_sessions,
|
322
|
+
preserve_session_refresh_token=preserve_session_refresh_token,
|
323
|
+
access_token=access_token,
|
324
|
+
)
|
325
|
+
except HTTPException as he:
|
326
|
+
global_object_square_logger.logger.error(he, exc_info=True)
|
327
|
+
return JSONResponse(status_code=he.status_code, content=he.detail)
|
1973
328
|
except Exception as e:
|
1974
|
-
"""
|
1975
|
-
rollback logic
|
1976
|
-
"""
|
1977
329
|
global_object_square_logger.logger.error(e, exc_info=True)
|
1978
330
|
output_content = get_api_output_in_standard_format(
|
1979
|
-
message=messages["GENERIC_500"],
|
1980
|
-
log=str(e),
|
331
|
+
message=messages["GENERIC_500"], log=str(e)
|
1981
332
|
)
|
1982
333
|
return JSONResponse(
|
1983
334
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
@@ -1991,102 +342,19 @@ async def validate_and_get_payload_from_token_v0(
|
|
1991
342
|
token: Annotated[str, Header()],
|
1992
343
|
token_type: TokenType = Query(...),
|
1993
344
|
):
|
1994
|
-
|
1995
345
|
try:
|
1996
|
-
|
1997
|
-
|
1998
|
-
|
1999
|
-
|
2000
|
-
|
2001
|
-
|
2002
|
-
|
2003
|
-
|
2004
|
-
token, config_str_secret_key_for_access_token
|
2005
|
-
)
|
2006
|
-
elif token_type == TokenType.refresh_token:
|
2007
|
-
local_dict_token_payload = get_jwt_payload(
|
2008
|
-
token, config_str_secret_key_for_refresh_token
|
2009
|
-
)
|
2010
|
-
local_list_response_user_session = global_object_square_database_helper.get_rows_v0(
|
2011
|
-
database_name=global_string_database_name,
|
2012
|
-
schema_name=global_string_schema_name,
|
2013
|
-
table_name=UserSession.__tablename__,
|
2014
|
-
filters=FiltersV0(
|
2015
|
-
root={
|
2016
|
-
UserSession.user_session_refresh_token.name: FilterConditionsV0(
|
2017
|
-
eq=token
|
2018
|
-
),
|
2019
|
-
UserSession.user_id.name: FilterConditionsV0(
|
2020
|
-
eq=local_dict_token_payload["user_id"]
|
2021
|
-
),
|
2022
|
-
}
|
2023
|
-
),
|
2024
|
-
)[
|
2025
|
-
"data"
|
2026
|
-
][
|
2027
|
-
"main"
|
2028
|
-
]
|
2029
|
-
if len(local_list_response_user_session) != 1:
|
2030
|
-
output_content = get_api_output_in_standard_format(
|
2031
|
-
message=messages["INCORRECT_REFRESH_TOKEN"],
|
2032
|
-
log="refresh token valid but not present in database.",
|
2033
|
-
)
|
2034
|
-
raise HTTPException(
|
2035
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
2036
|
-
detail=output_content,
|
2037
|
-
)
|
2038
|
-
if local_dict_token_payload["app_id"] != app_id:
|
2039
|
-
output_content = get_api_output_in_standard_format(
|
2040
|
-
message=messages["GENERIC_400"],
|
2041
|
-
log=f"app_id: {app_id} does not match with token app_id: {local_dict_token_payload['app_id']}.",
|
2042
|
-
)
|
2043
|
-
raise HTTPException(
|
2044
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
2045
|
-
detail=output_content,
|
2046
|
-
)
|
2047
|
-
except HTTPException as http_exception:
|
2048
|
-
raise
|
2049
|
-
except Exception as error:
|
2050
|
-
output_content = None
|
2051
|
-
if token_type == TokenType.access_token:
|
2052
|
-
output_content = get_api_output_in_standard_format(
|
2053
|
-
message=messages["INCORRECT_ACCESS_TOKEN"], log=str(error)
|
2054
|
-
)
|
2055
|
-
elif token_type == TokenType.refresh_token:
|
2056
|
-
output_content = get_api_output_in_standard_format(
|
2057
|
-
message=messages["INCORRECT_REFRESH_TOKEN"], log=str(error)
|
2058
|
-
)
|
2059
|
-
|
2060
|
-
raise HTTPException(
|
2061
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
2062
|
-
detail=output_content,
|
2063
|
-
)
|
2064
|
-
|
2065
|
-
"""
|
2066
|
-
main process
|
2067
|
-
"""
|
2068
|
-
# pass
|
2069
|
-
"""
|
2070
|
-
return value
|
2071
|
-
"""
|
2072
|
-
output_content = get_api_output_in_standard_format(
|
2073
|
-
message=messages["GENERIC_READ_SUCCESSFUL"],
|
2074
|
-
data={"main": local_dict_token_payload},
|
2075
|
-
)
|
2076
|
-
return JSONResponse(status_code=status.HTTP_200_OK, content=output_content)
|
2077
|
-
except HTTPException as http_exception:
|
2078
|
-
global_object_square_logger.logger.error(http_exception, exc_info=True)
|
2079
|
-
return JSONResponse(
|
2080
|
-
status_code=http_exception.status_code, content=http_exception.detail
|
2081
|
-
)
|
346
|
+
return util_validate_and_get_payload_from_token_v0(
|
347
|
+
app_id=app_id,
|
348
|
+
token=token,
|
349
|
+
token_type=token_type,
|
350
|
+
)
|
351
|
+
except HTTPException as he:
|
352
|
+
global_object_square_logger.logger.error(he, exc_info=True)
|
353
|
+
return JSONResponse(status_code=he.status_code, content=he.detail)
|
2082
354
|
except Exception as e:
|
2083
|
-
"""
|
2084
|
-
rollback logic
|
2085
|
-
"""
|
2086
355
|
global_object_square_logger.logger.error(e, exc_info=True)
|
2087
356
|
output_content = get_api_output_in_standard_format(
|
2088
|
-
message=messages["GENERIC_500"],
|
2089
|
-
log=str(e),
|
357
|
+
message=messages["GENERIC_500"], log=str(e)
|
2090
358
|
)
|
2091
359
|
return JSONResponse(
|
2092
360
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
@@ -2100,221 +368,22 @@ async def update_user_recovery_methods_v0(
|
|
2100
368
|
recovery_methods_to_add: List[RecoveryMethodEnum] = None,
|
2101
369
|
recovery_methods_to_remove: List[RecoveryMethodEnum] = None,
|
2102
370
|
):
|
2103
|
-
if recovery_methods_to_add is None:
|
2104
|
-
recovery_methods_to_add = []
|
2105
|
-
if recovery_methods_to_remove is None:
|
2106
|
-
recovery_methods_to_remove = []
|
2107
371
|
try:
|
2108
|
-
|
2109
|
-
|
2110
|
-
|
2111
|
-
|
2112
|
-
|
2113
|
-
|
2114
|
-
|
2115
|
-
|
2116
|
-
)
|
2117
|
-
except Exception as error:
|
2118
|
-
output_content = get_api_output_in_standard_format(
|
2119
|
-
message=messages["INCORRECT_ACCESS_TOKEN"], log=str(error)
|
2120
|
-
)
|
2121
|
-
raise HTTPException(
|
2122
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
2123
|
-
detail=output_content,
|
2124
|
-
)
|
2125
|
-
user_id = local_dict_access_token_payload["user_id"]
|
2126
|
-
|
2127
|
-
recovery_methods_to_add = list(set(x.value for x in recovery_methods_to_add))
|
2128
|
-
recovery_methods_to_remove = list(
|
2129
|
-
set(x.value for x in recovery_methods_to_remove)
|
2130
|
-
)
|
2131
|
-
|
2132
|
-
# check if recovery_methods_to_add and recovery_methods_to_remove don't have common ids.
|
2133
|
-
local_list_common_recovery_methods = set(recovery_methods_to_add) & set(
|
2134
|
-
recovery_methods_to_remove
|
2135
|
-
)
|
2136
|
-
if len(local_list_common_recovery_methods) > 0:
|
2137
|
-
output_content = get_api_output_in_standard_format(
|
2138
|
-
message=messages["GENERIC_400"],
|
2139
|
-
log=f"invalid recovery_methods: {list(local_list_common_recovery_methods)}, present in both add list and remove list.",
|
2140
|
-
)
|
2141
|
-
raise HTTPException(
|
2142
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
2143
|
-
detail=output_content,
|
2144
|
-
)
|
2145
|
-
# check if user's email is verified in user profile.
|
2146
|
-
# maybe too harsh to reject the request entirely,
|
2147
|
-
# but for practical purposes this api call should be used for 1 recovery method at a time, so it's not too bad.
|
2148
|
-
if RecoveryMethodEnum.EMAIL.value in recovery_methods_to_add:
|
2149
|
-
local_list_response_user_profile = (
|
2150
|
-
global_object_square_database_helper.get_rows_v0(
|
2151
|
-
database_name=global_string_database_name,
|
2152
|
-
schema_name=global_string_schema_name,
|
2153
|
-
table_name=UserProfile.__tablename__,
|
2154
|
-
filters=FiltersV0(
|
2155
|
-
root={
|
2156
|
-
UserProfile.user_id.name: FilterConditionsV0(eq=user_id),
|
2157
|
-
}
|
2158
|
-
),
|
2159
|
-
)["data"]["main"]
|
2160
|
-
)
|
2161
|
-
if len(local_list_response_user_profile) != 1:
|
2162
|
-
# maybe this should raise 500 as this error will not occur if code runs correctly.
|
2163
|
-
output_content = get_api_output_in_standard_format(
|
2164
|
-
message=messages["GENERIC_400"],
|
2165
|
-
log=f"user_id: {user_id} does not have a profile.",
|
2166
|
-
)
|
2167
|
-
raise HTTPException(
|
2168
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
2169
|
-
detail=output_content,
|
2170
|
-
)
|
2171
|
-
local_dict_user_profile = local_list_response_user_profile[0]
|
2172
|
-
if not local_dict_user_profile[
|
2173
|
-
UserProfile.user_profile_email_verified.name
|
2174
|
-
]:
|
2175
|
-
output_content = get_api_output_in_standard_format(
|
2176
|
-
message=messages["EMAIL_NOT_VERIFIED"],
|
2177
|
-
log=f"user_id: {user_id} does not have email verified.",
|
2178
|
-
)
|
2179
|
-
raise HTTPException(
|
2180
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
2181
|
-
detail=output_content,
|
2182
|
-
)
|
2183
|
-
"""
|
2184
|
-
main process
|
2185
|
-
"""
|
2186
|
-
# logic for adding new recovery_methods
|
2187
|
-
local_list_response_user_recovery_methods = (
|
2188
|
-
global_object_square_database_helper.get_rows_v0(
|
2189
|
-
database_name=global_string_database_name,
|
2190
|
-
schema_name=global_string_schema_name,
|
2191
|
-
table_name=UserRecoveryMethod.__tablename__,
|
2192
|
-
filters=FiltersV0(
|
2193
|
-
root={
|
2194
|
-
UserRecoveryMethod.user_id.name: FilterConditionsV0(eq=user_id)
|
2195
|
-
}
|
2196
|
-
),
|
2197
|
-
)["data"]["main"]
|
2198
|
-
)
|
2199
|
-
local_list_new_recovery_methods = [
|
2200
|
-
{
|
2201
|
-
UserRecoveryMethod.user_id.name: user_id,
|
2202
|
-
UserRecoveryMethod.user_recovery_method_name.name: x,
|
2203
|
-
}
|
2204
|
-
for x in recovery_methods_to_add
|
2205
|
-
if x
|
2206
|
-
not in [
|
2207
|
-
y[UserRecoveryMethod.user_recovery_method_name.name]
|
2208
|
-
for y in local_list_response_user_recovery_methods
|
2209
|
-
]
|
2210
|
-
]
|
2211
|
-
if len(local_list_new_recovery_methods) > 0:
|
2212
|
-
global_object_square_database_helper.insert_rows_v0(
|
2213
|
-
database_name=global_string_database_name,
|
2214
|
-
schema_name=global_string_schema_name,
|
2215
|
-
table_name=UserRecoveryMethod.__tablename__,
|
2216
|
-
data=local_list_new_recovery_methods,
|
2217
|
-
)
|
2218
|
-
|
2219
|
-
# logic for removing recovery_methods
|
2220
|
-
remove_old_backup_codes = (
|
2221
|
-
RecoveryMethodEnum.BACKUP_CODE.value in recovery_methods_to_remove
|
2222
|
-
)
|
2223
|
-
old_backup_code_hashes = None
|
2224
|
-
if remove_old_backup_codes:
|
2225
|
-
# delete existing backup codes if any
|
2226
|
-
old_backup_code_hashes = global_object_square_database_helper.get_rows_v0(
|
2227
|
-
database_name=global_string_database_name,
|
2228
|
-
schema_name=global_string_schema_name,
|
2229
|
-
table_name=UserVerificationCode.__tablename__,
|
2230
|
-
filters=FiltersV0(
|
2231
|
-
root={
|
2232
|
-
UserVerificationCode.user_id.name: FilterConditionsV0(
|
2233
|
-
eq=user_id
|
2234
|
-
),
|
2235
|
-
UserVerificationCode.user_verification_code_type.name: FilterConditionsV0(
|
2236
|
-
eq=VerificationCodeTypeEnum.BACKUP_CODE_RECOVERY.value
|
2237
|
-
),
|
2238
|
-
}
|
2239
|
-
),
|
2240
|
-
columns=[UserVerificationCode.user_verification_code_hash.name],
|
2241
|
-
)["data"]["main"]
|
2242
|
-
global_object_square_database_helper.delete_rows_v0(
|
2243
|
-
database_name=global_string_database_name,
|
2244
|
-
schema_name=global_string_schema_name,
|
2245
|
-
table_name=UserRecoveryMethod.__tablename__,
|
2246
|
-
filters=FiltersV0(
|
2247
|
-
root={
|
2248
|
-
UserRecoveryMethod.user_id.name: FilterConditionsV0(eq=user_id),
|
2249
|
-
UserRecoveryMethod.user_recovery_method_name.name: FilterConditionsV0(
|
2250
|
-
in_=recovery_methods_to_remove
|
2251
|
-
),
|
2252
|
-
}
|
2253
|
-
),
|
2254
|
-
)
|
2255
|
-
if remove_old_backup_codes and old_backup_code_hashes:
|
2256
|
-
global_object_square_database_helper.delete_rows_v0(
|
2257
|
-
database_name=global_string_database_name,
|
2258
|
-
schema_name=global_string_schema_name,
|
2259
|
-
table_name=UserVerificationCode.__tablename__,
|
2260
|
-
filters=FiltersV0(
|
2261
|
-
root={
|
2262
|
-
UserVerificationCode.user_verification_code_hash.name: FilterConditionsV0(
|
2263
|
-
in_=[
|
2264
|
-
x[UserVerificationCode.user_verification_code_hash.name]
|
2265
|
-
for x in old_backup_code_hashes
|
2266
|
-
]
|
2267
|
-
),
|
2268
|
-
}
|
2269
|
-
),
|
2270
|
-
)
|
2271
|
-
|
2272
|
-
"""
|
2273
|
-
return value
|
2274
|
-
"""
|
2275
|
-
# get latest recovery_methods
|
2276
|
-
local_list_response_user_recovery_methods = (
|
2277
|
-
global_object_square_database_helper.get_rows_v0(
|
2278
|
-
database_name=global_string_database_name,
|
2279
|
-
schema_name=global_string_schema_name,
|
2280
|
-
table_name=UserRecoveryMethod.__tablename__,
|
2281
|
-
filters=FiltersV0(
|
2282
|
-
root={
|
2283
|
-
UserRecoveryMethod.user_id.name: FilterConditionsV0(eq=user_id)
|
2284
|
-
}
|
2285
|
-
),
|
2286
|
-
)["data"]["main"]
|
2287
|
-
)
|
2288
|
-
output_content = get_api_output_in_standard_format(
|
2289
|
-
message=messages["GENERIC_UPDATE_SUCCESSFUL"],
|
2290
|
-
data={
|
2291
|
-
"main": [
|
2292
|
-
x[UserRecoveryMethod.user_recovery_method_name.name]
|
2293
|
-
for x in local_list_response_user_recovery_methods
|
2294
|
-
]
|
2295
|
-
},
|
2296
|
-
)
|
2297
|
-
return JSONResponse(
|
2298
|
-
status_code=status.HTTP_200_OK,
|
2299
|
-
content=output_content,
|
2300
|
-
)
|
2301
|
-
except HTTPException as http_exception:
|
2302
|
-
global_object_square_logger.logger.error(http_exception, exc_info=True)
|
2303
|
-
return JSONResponse(
|
2304
|
-
status_code=http_exception.status_code, content=http_exception.detail
|
2305
|
-
)
|
372
|
+
return util_update_user_recovery_methods_v0(
|
373
|
+
access_token=access_token,
|
374
|
+
recovery_methods_to_add=recovery_methods_to_add,
|
375
|
+
recovery_methods_to_remove=recovery_methods_to_remove,
|
376
|
+
)
|
377
|
+
except HTTPException as he:
|
378
|
+
global_object_square_logger.logger.error(he, exc_info=True)
|
379
|
+
return JSONResponse(status_code=he.status_code, content=he.detail)
|
2306
380
|
except Exception as e:
|
2307
|
-
"""
|
2308
|
-
rollback logic
|
2309
|
-
"""
|
2310
381
|
global_object_square_logger.logger.error(e, exc_info=True)
|
2311
382
|
output_content = get_api_output_in_standard_format(
|
2312
|
-
message=messages["GENERIC_500"],
|
2313
|
-
log=str(e),
|
383
|
+
message=messages["GENERIC_500"], log=str(e)
|
2314
384
|
)
|
2315
385
|
return JSONResponse(
|
2316
|
-
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
2317
|
-
content=output_content,
|
386
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
2318
387
|
)
|
2319
388
|
|
2320
389
|
|
@@ -2323,136 +392,17 @@ async def update_user_recovery_methods_v0(
|
|
2323
392
|
async def generate_account_backup_codes_v0(
|
2324
393
|
access_token: Annotated[str, Header()],
|
2325
394
|
):
|
2326
|
-
|
2327
395
|
try:
|
2328
|
-
|
2329
|
-
|
2330
|
-
"""
|
2331
|
-
try:
|
2332
|
-
local_dict_access_token_payload = get_jwt_payload(
|
2333
|
-
access_token, config_str_secret_key_for_access_token
|
2334
|
-
)
|
2335
|
-
except Exception as error:
|
2336
|
-
output_content = get_api_output_in_standard_format(
|
2337
|
-
message=messages["INCORRECT_ACCESS_TOKEN"], log=str(error)
|
2338
|
-
)
|
2339
|
-
raise HTTPException(
|
2340
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
2341
|
-
detail=output_content,
|
2342
|
-
)
|
2343
|
-
user_id = local_dict_access_token_payload["user_id"]
|
2344
|
-
# check if user has recovery method enabled
|
2345
|
-
local_list_response_user_recovery_methods = global_object_square_database_helper.get_rows_v0(
|
2346
|
-
database_name=global_string_database_name,
|
2347
|
-
schema_name=global_string_schema_name,
|
2348
|
-
table_name=UserRecoveryMethod.__tablename__,
|
2349
|
-
filters=FiltersV0(
|
2350
|
-
root={
|
2351
|
-
UserRecoveryMethod.user_id.name: FilterConditionsV0(eq=user_id),
|
2352
|
-
UserRecoveryMethod.user_recovery_method_name.name: FilterConditionsV0(
|
2353
|
-
eq=RecoveryMethodEnum.BACKUP_CODE.value
|
2354
|
-
),
|
2355
|
-
}
|
2356
|
-
),
|
2357
|
-
)[
|
2358
|
-
"data"
|
2359
|
-
][
|
2360
|
-
"main"
|
2361
|
-
]
|
2362
|
-
if len(local_list_response_user_recovery_methods) != 1:
|
2363
|
-
output_content = get_api_output_in_standard_format(
|
2364
|
-
message=messages["RECOVERY_METHOD_NOT_ENABLED"],
|
2365
|
-
log=f"user_id: {user_id} does not have backup codes recovery method enabled.",
|
2366
|
-
)
|
2367
|
-
raise HTTPException(
|
2368
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
2369
|
-
detail=output_content,
|
2370
|
-
)
|
2371
|
-
"""
|
2372
|
-
main process
|
2373
|
-
"""
|
2374
|
-
# delete existing backup codes if any
|
2375
|
-
old_backup_code_hashes = global_object_square_database_helper.get_rows_v0(
|
2376
|
-
database_name=global_string_database_name,
|
2377
|
-
schema_name=global_string_schema_name,
|
2378
|
-
table_name=UserVerificationCode.__tablename__,
|
2379
|
-
filters=FiltersV0(
|
2380
|
-
root={
|
2381
|
-
UserVerificationCode.user_id.name: FilterConditionsV0(eq=user_id),
|
2382
|
-
UserVerificationCode.user_verification_code_type.name: FilterConditionsV0(
|
2383
|
-
eq=VerificationCodeTypeEnum.BACKUP_CODE_RECOVERY.value
|
2384
|
-
),
|
2385
|
-
}
|
2386
|
-
),
|
2387
|
-
columns=[UserVerificationCode.user_verification_code_hash.name],
|
2388
|
-
)["data"]["main"]
|
2389
|
-
|
2390
|
-
# generate backup codes
|
2391
|
-
backup_codes = []
|
2392
|
-
db_data = []
|
2393
|
-
|
2394
|
-
for i in range(NUMBER_OF_RECOVERY_CODES):
|
2395
|
-
backup_code = str(uuid.uuid4())
|
2396
|
-
backup_codes.append(backup_code)
|
2397
|
-
# hash the backup code
|
2398
|
-
local_str_hashed_backup_code = bcrypt.hashpw(
|
2399
|
-
backup_code.encode("utf-8"), bcrypt.gensalt()
|
2400
|
-
).decode("utf-8")
|
2401
|
-
|
2402
|
-
db_data.append(
|
2403
|
-
{
|
2404
|
-
UserVerificationCode.user_id.name: user_id,
|
2405
|
-
UserVerificationCode.user_verification_code_type.name: VerificationCodeTypeEnum.BACKUP_CODE_RECOVERY.value,
|
2406
|
-
UserVerificationCode.user_verification_code_hash.name: local_str_hashed_backup_code,
|
2407
|
-
}
|
2408
|
-
)
|
2409
|
-
global_object_square_database_helper.insert_rows_v0(
|
2410
|
-
database_name=global_string_database_name,
|
2411
|
-
schema_name=global_string_schema_name,
|
2412
|
-
table_name=UserVerificationCode.__tablename__,
|
2413
|
-
data=db_data,
|
2414
|
-
)
|
2415
|
-
global_object_square_database_helper.delete_rows_v0(
|
2416
|
-
database_name=global_string_database_name,
|
2417
|
-
schema_name=global_string_schema_name,
|
2418
|
-
table_name=UserVerificationCode.__tablename__,
|
2419
|
-
filters=FiltersV0(
|
2420
|
-
root={
|
2421
|
-
UserVerificationCode.user_verification_code_hash.name: FilterConditionsV0(
|
2422
|
-
in_=[
|
2423
|
-
x[UserVerificationCode.user_verification_code_hash.name]
|
2424
|
-
for x in old_backup_code_hashes
|
2425
|
-
]
|
2426
|
-
),
|
2427
|
-
}
|
2428
|
-
),
|
2429
|
-
)
|
2430
|
-
"""
|
2431
|
-
return value
|
2432
|
-
"""
|
2433
|
-
output_content = get_api_output_in_standard_format(
|
2434
|
-
message=messages["GENERIC_CREATION_SUCCESSFUL"],
|
2435
|
-
data={
|
2436
|
-
"main": {
|
2437
|
-
"user_id": user_id,
|
2438
|
-
"backup_codes": backup_codes,
|
2439
|
-
}
|
2440
|
-
},
|
2441
|
-
)
|
2442
|
-
return JSONResponse(status_code=status.HTTP_200_OK, content=output_content)
|
2443
|
-
except HTTPException as http_exception:
|
2444
|
-
global_object_square_logger.logger.error(http_exception, exc_info=True)
|
2445
|
-
return JSONResponse(
|
2446
|
-
status_code=http_exception.status_code, content=http_exception.detail
|
396
|
+
return util_generate_account_backup_codes_v0(
|
397
|
+
access_token=access_token,
|
2447
398
|
)
|
399
|
+
except HTTPException as he:
|
400
|
+
global_object_square_logger.logger.error(he, exc_info=True)
|
401
|
+
return JSONResponse(status_code=he.status_code, content=he.detail)
|
2448
402
|
except Exception as e:
|
2449
|
-
"""
|
2450
|
-
rollback logic
|
2451
|
-
"""
|
2452
403
|
global_object_square_logger.logger.error(e, exc_info=True)
|
2453
404
|
output_content = get_api_output_in_standard_format(
|
2454
|
-
message=messages["GENERIC_500"],
|
2455
|
-
log=str(e),
|
405
|
+
message=messages["GENERIC_500"], log=str(e)
|
2456
406
|
)
|
2457
407
|
return JSONResponse(
|
2458
408
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
@@ -2470,272 +420,20 @@ async def reset_password_and_login_using_backup_code_v0(
|
|
2470
420
|
app_id = body.app_id
|
2471
421
|
logout_other_sessions = body.logout_other_sessions
|
2472
422
|
try:
|
2473
|
-
|
2474
|
-
|
2475
|
-
|
2476
|
-
|
2477
|
-
|
2478
|
-
|
2479
|
-
|
2480
|
-
|
2481
|
-
|
2482
|
-
|
2483
|
-
root={User.user_username.name: FilterConditionsV0(eq=username)}
|
2484
|
-
),
|
2485
|
-
)["data"]["main"]
|
2486
|
-
)
|
2487
|
-
if len(local_list_authentication_user_response) != 1:
|
2488
|
-
output_content = get_api_output_in_standard_format(
|
2489
|
-
message=messages["INCORRECT_USERNAME"],
|
2490
|
-
log=f"incorrect username: {username}.",
|
2491
|
-
)
|
2492
|
-
raise HTTPException(
|
2493
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
2494
|
-
detail=output_content,
|
2495
|
-
)
|
2496
|
-
user_id = local_list_authentication_user_response[0][User.user_id.name]
|
2497
|
-
# check if user has SELF auth provider
|
2498
|
-
local_list_response_user_auth_provider = (
|
2499
|
-
global_object_square_database_helper.get_rows_v0(
|
2500
|
-
database_name=global_string_database_name,
|
2501
|
-
schema_name=global_string_schema_name,
|
2502
|
-
table_name=UserAuthProvider.__tablename__,
|
2503
|
-
filters=FiltersV0(
|
2504
|
-
root={
|
2505
|
-
UserAuthProvider.user_id.name: FilterConditionsV0(eq=user_id),
|
2506
|
-
UserAuthProvider.auth_provider.name: FilterConditionsV0(
|
2507
|
-
eq=AuthProviderEnum.SELF.value
|
2508
|
-
),
|
2509
|
-
}
|
2510
|
-
),
|
2511
|
-
)["data"]["main"]
|
2512
|
-
)
|
2513
|
-
if len(local_list_response_user_auth_provider) != 1:
|
2514
|
-
output_content = get_api_output_in_standard_format(
|
2515
|
-
message=messages["INCORRECT_AUTH_PROVIDER"],
|
2516
|
-
log=f"user_id: {user_id} does not have {AuthProviderEnum.SELF.value} auth provider.",
|
2517
|
-
)
|
2518
|
-
raise HTTPException(
|
2519
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
2520
|
-
detail=output_content,
|
2521
|
-
)
|
2522
|
-
# check if user has recovery method enabled
|
2523
|
-
local_list_response_user_recovery_methods = global_object_square_database_helper.get_rows_v0(
|
2524
|
-
database_name=global_string_database_name,
|
2525
|
-
schema_name=global_string_schema_name,
|
2526
|
-
table_name=UserRecoveryMethod.__tablename__,
|
2527
|
-
filters=FiltersV0(
|
2528
|
-
root={
|
2529
|
-
UserRecoveryMethod.user_id.name: FilterConditionsV0(eq=user_id),
|
2530
|
-
UserRecoveryMethod.user_recovery_method_name.name: FilterConditionsV0(
|
2531
|
-
eq=RecoveryMethodEnum.BACKUP_CODE.value
|
2532
|
-
),
|
2533
|
-
}
|
2534
|
-
),
|
2535
|
-
)[
|
2536
|
-
"data"
|
2537
|
-
][
|
2538
|
-
"main"
|
2539
|
-
]
|
2540
|
-
if len(local_list_response_user_recovery_methods) != 1:
|
2541
|
-
output_content = get_api_output_in_standard_format(
|
2542
|
-
message=messages["RECOVERY_METHOD_NOT_ENABLED"],
|
2543
|
-
log=f"user_id: {user_id} does not have backup codes recovery method enabled.",
|
2544
|
-
)
|
2545
|
-
raise HTTPException(
|
2546
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
2547
|
-
detail=output_content,
|
2548
|
-
)
|
2549
|
-
# validate if user is assigned to the app.
|
2550
|
-
# not checking [skipping] if the app exists, as it is not required for this endpoint.
|
2551
|
-
local_list_response_user_app = global_object_square_database_helper.get_rows_v0(
|
2552
|
-
database_name=global_string_database_name,
|
2553
|
-
schema_name=global_string_schema_name,
|
2554
|
-
table_name=UserApp.__tablename__,
|
2555
|
-
filters=FiltersV0(
|
2556
|
-
root={
|
2557
|
-
UserApp.user_id.name: FilterConditionsV0(eq=user_id),
|
2558
|
-
UserApp.app_id.name: FilterConditionsV0(eq=app_id),
|
2559
|
-
}
|
2560
|
-
),
|
2561
|
-
)["data"]["main"]
|
2562
|
-
if len(local_list_response_user_app) == 0:
|
2563
|
-
output_content = get_api_output_in_standard_format(
|
2564
|
-
message=messages["GENERIC_400"],
|
2565
|
-
log=f"user_id: {user_id} is not assigned to app_id: {app_id}.",
|
2566
|
-
)
|
2567
|
-
raise HTTPException(
|
2568
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
2569
|
-
detail=output_content,
|
2570
|
-
)
|
2571
|
-
"""
|
2572
|
-
main process
|
2573
|
-
"""
|
2574
|
-
# validate backup code
|
2575
|
-
local_list_response_user_verification_code = global_object_square_database_helper.get_rows_v0(
|
2576
|
-
database_name=global_string_database_name,
|
2577
|
-
schema_name=global_string_schema_name,
|
2578
|
-
table_name=UserVerificationCode.__tablename__,
|
2579
|
-
filters=FiltersV0(
|
2580
|
-
root={
|
2581
|
-
UserVerificationCode.user_id.name: FilterConditionsV0(eq=user_id),
|
2582
|
-
UserVerificationCode.user_verification_code_type.name: FilterConditionsV0(
|
2583
|
-
eq=VerificationCodeTypeEnum.BACKUP_CODE_RECOVERY.value
|
2584
|
-
),
|
2585
|
-
UserVerificationCode.user_verification_code_expires_at.name: FilterConditionsV0(
|
2586
|
-
is_null=True
|
2587
|
-
),
|
2588
|
-
UserVerificationCode.user_verification_code_used_at.name: FilterConditionsV0(
|
2589
|
-
is_null=True
|
2590
|
-
),
|
2591
|
-
}
|
2592
|
-
),
|
2593
|
-
columns=[UserVerificationCode.user_verification_code_hash.name],
|
2594
|
-
)[
|
2595
|
-
"data"
|
2596
|
-
][
|
2597
|
-
"main"
|
2598
|
-
]
|
2599
|
-
# find the backup code in the list
|
2600
|
-
local_list_response_user_verification_code = [
|
2601
|
-
x
|
2602
|
-
for x in local_list_response_user_verification_code
|
2603
|
-
if bcrypt.checkpw(
|
2604
|
-
backup_code.encode("utf-8"),
|
2605
|
-
x[UserVerificationCode.user_verification_code_hash.name].encode(
|
2606
|
-
"utf-8"
|
2607
|
-
),
|
2608
|
-
)
|
2609
|
-
]
|
2610
|
-
if len(local_list_response_user_verification_code) != 1:
|
2611
|
-
output_content = get_api_output_in_standard_format(
|
2612
|
-
message=messages["INCORRECT_BACKUP_CODE"],
|
2613
|
-
log=f"incorrect backup code: {backup_code} for user_id: {user_id}.",
|
2614
|
-
)
|
2615
|
-
raise HTTPException(
|
2616
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
2617
|
-
detail=output_content,
|
2618
|
-
)
|
2619
|
-
# hash the new password
|
2620
|
-
local_str_hashed_password = bcrypt.hashpw(
|
2621
|
-
new_password.encode("utf-8"), bcrypt.gensalt()
|
2622
|
-
).decode("utf-8")
|
2623
|
-
# update the password
|
2624
|
-
global_object_square_database_helper.edit_rows_v0(
|
2625
|
-
database_name=global_string_database_name,
|
2626
|
-
schema_name=global_string_schema_name,
|
2627
|
-
table_name=UserCredential.__tablename__,
|
2628
|
-
filters=FiltersV0(
|
2629
|
-
root={
|
2630
|
-
UserCredential.user_id.name: FilterConditionsV0(eq=user_id),
|
2631
|
-
}
|
2632
|
-
),
|
2633
|
-
data={
|
2634
|
-
UserCredential.user_credential_hashed_password.name: local_str_hashed_password,
|
2635
|
-
},
|
2636
|
-
)
|
2637
|
-
# mark the backup code as used
|
2638
|
-
global_object_square_database_helper.edit_rows_v0(
|
2639
|
-
database_name=global_string_database_name,
|
2640
|
-
schema_name=global_string_schema_name,
|
2641
|
-
table_name=UserVerificationCode.__tablename__,
|
2642
|
-
filters=FiltersV0(
|
2643
|
-
root={
|
2644
|
-
UserVerificationCode.user_id.name: FilterConditionsV0(eq=user_id),
|
2645
|
-
UserVerificationCode.user_verification_code_type.name: FilterConditionsV0(
|
2646
|
-
eq=VerificationCodeTypeEnum.BACKUP_CODE_RECOVERY.value
|
2647
|
-
),
|
2648
|
-
UserVerificationCode.user_verification_code_hash.name: FilterConditionsV0(
|
2649
|
-
eq=local_list_response_user_verification_code[0][
|
2650
|
-
UserVerificationCode.user_verification_code_hash.name
|
2651
|
-
]
|
2652
|
-
),
|
2653
|
-
}
|
2654
|
-
),
|
2655
|
-
data={
|
2656
|
-
UserVerificationCode.user_verification_code_used_at.name: datetime.now(
|
2657
|
-
timezone.utc
|
2658
|
-
).strftime("%Y-%m-%d %H:%M:%S.%f+00"),
|
2659
|
-
},
|
2660
|
-
)
|
2661
|
-
if logout_other_sessions:
|
2662
|
-
# delete all sessions for user
|
2663
|
-
global_object_square_database_helper.delete_rows_v0(
|
2664
|
-
database_name=global_string_database_name,
|
2665
|
-
schema_name=global_string_schema_name,
|
2666
|
-
table_name=UserSession.__tablename__,
|
2667
|
-
filters=FiltersV0(
|
2668
|
-
root={
|
2669
|
-
UserSession.user_id.name: FilterConditionsV0(eq=user_id),
|
2670
|
-
}
|
2671
|
-
),
|
2672
|
-
)
|
2673
|
-
# generate access token and refresh token
|
2674
|
-
local_dict_access_token_payload = {
|
2675
|
-
"app_id": app_id,
|
2676
|
-
"user_id": user_id,
|
2677
|
-
"exp": datetime.now(timezone.utc)
|
2678
|
-
+ timedelta(minutes=config_int_access_token_valid_minutes),
|
2679
|
-
}
|
2680
|
-
local_str_access_token = jwt.encode(
|
2681
|
-
local_dict_access_token_payload, config_str_secret_key_for_access_token
|
2682
|
-
)
|
2683
|
-
local_object_refresh_token_expiry_time = datetime.now(timezone.utc) + timedelta(
|
2684
|
-
minutes=config_int_refresh_token_valid_minutes
|
2685
|
-
)
|
2686
|
-
local_dict_refresh_token_payload = {
|
2687
|
-
"app_id": app_id,
|
2688
|
-
"user_id": user_id,
|
2689
|
-
"exp": local_object_refresh_token_expiry_time,
|
2690
|
-
}
|
2691
|
-
local_str_refresh_token = jwt.encode(
|
2692
|
-
local_dict_refresh_token_payload, config_str_secret_key_for_refresh_token
|
2693
|
-
)
|
2694
|
-
# insert the refresh token in the database
|
2695
|
-
global_object_square_database_helper.insert_rows_v0(
|
2696
|
-
database_name=global_string_database_name,
|
2697
|
-
schema_name=global_string_schema_name,
|
2698
|
-
table_name=UserSession.__tablename__,
|
2699
|
-
data=[
|
2700
|
-
{
|
2701
|
-
UserSession.user_id.name: user_id,
|
2702
|
-
UserSession.app_id.name: app_id,
|
2703
|
-
UserSession.user_session_refresh_token.name: local_str_refresh_token,
|
2704
|
-
UserSession.user_session_expiry_time.name: local_object_refresh_token_expiry_time.strftime(
|
2705
|
-
"%Y-%m-%d %H:%M:%S.%f+00"
|
2706
|
-
),
|
2707
|
-
}
|
2708
|
-
],
|
2709
|
-
)
|
2710
|
-
"""
|
2711
|
-
return value
|
2712
|
-
"""
|
2713
|
-
output_content = get_api_output_in_standard_format(
|
2714
|
-
message=messages["GENERIC_ACTION_SUCCESSFUL"],
|
2715
|
-
data={
|
2716
|
-
"main": {
|
2717
|
-
"user_id": user_id,
|
2718
|
-
"access_token": local_str_access_token,
|
2719
|
-
"refresh_token": local_str_refresh_token,
|
2720
|
-
"refresh_token_expiry_time": local_object_refresh_token_expiry_time.isoformat(),
|
2721
|
-
}
|
2722
|
-
},
|
2723
|
-
)
|
2724
|
-
|
2725
|
-
return JSONResponse(status_code=status.HTTP_200_OK, content=output_content)
|
2726
|
-
except HTTPException as http_exception:
|
2727
|
-
global_object_square_logger.logger.error(http_exception, exc_info=True)
|
2728
|
-
return JSONResponse(
|
2729
|
-
status_code=http_exception.status_code, content=http_exception.detail
|
2730
|
-
)
|
423
|
+
return util_reset_password_and_login_using_backup_code_v0(
|
424
|
+
backup_code=backup_code,
|
425
|
+
username=username,
|
426
|
+
new_password=new_password,
|
427
|
+
app_id=app_id,
|
428
|
+
logout_other_sessions=logout_other_sessions,
|
429
|
+
)
|
430
|
+
except HTTPException as he:
|
431
|
+
global_object_square_logger.logger.error(he, exc_info=True)
|
432
|
+
return JSONResponse(status_code=he.status_code, content=he.detail)
|
2731
433
|
except Exception as e:
|
2732
|
-
"""
|
2733
|
-
rollback logic
|
2734
|
-
"""
|
2735
434
|
global_object_square_logger.logger.error(e, exc_info=True)
|
2736
435
|
output_content = get_api_output_in_standard_format(
|
2737
|
-
message=messages["GENERIC_500"],
|
2738
|
-
log=str(e),
|
436
|
+
message=messages["GENERIC_500"], log=str(e)
|
2739
437
|
)
|
2740
438
|
return JSONResponse(
|
2741
439
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
@@ -2749,261 +447,16 @@ async def send_reset_password_email_v0(
|
|
2749
447
|
):
|
2750
448
|
username = body.username
|
2751
449
|
try:
|
2752
|
-
|
2753
|
-
|
2754
|
-
"""
|
2755
|
-
# validate username
|
2756
|
-
local_list_authentication_user_response = (
|
2757
|
-
global_object_square_database_helper.get_rows_v0(
|
2758
|
-
database_name=global_string_database_name,
|
2759
|
-
schema_name=global_string_schema_name,
|
2760
|
-
table_name=User.__tablename__,
|
2761
|
-
filters=FiltersV0(
|
2762
|
-
root={User.user_username.name: FilterConditionsV0(eq=username)}
|
2763
|
-
),
|
2764
|
-
)["data"]["main"]
|
2765
|
-
)
|
2766
|
-
if len(local_list_authentication_user_response) != 1:
|
2767
|
-
output_content = get_api_output_in_standard_format(
|
2768
|
-
message=messages["INCORRECT_USERNAME"],
|
2769
|
-
log=f"incorrect username: {username}.",
|
2770
|
-
)
|
2771
|
-
raise HTTPException(
|
2772
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
2773
|
-
detail=output_content,
|
2774
|
-
)
|
2775
|
-
user_id = local_list_authentication_user_response[0][User.user_id.name]
|
2776
|
-
# check if user has SELF auth provider
|
2777
|
-
local_list_response_user_auth_provider = (
|
2778
|
-
global_object_square_database_helper.get_rows_v0(
|
2779
|
-
database_name=global_string_database_name,
|
2780
|
-
schema_name=global_string_schema_name,
|
2781
|
-
table_name=UserAuthProvider.__tablename__,
|
2782
|
-
filters=FiltersV0(
|
2783
|
-
root={
|
2784
|
-
UserAuthProvider.user_id.name: FilterConditionsV0(eq=user_id),
|
2785
|
-
UserAuthProvider.auth_provider.name: FilterConditionsV0(
|
2786
|
-
eq=AuthProviderEnum.SELF.value
|
2787
|
-
),
|
2788
|
-
}
|
2789
|
-
),
|
2790
|
-
)["data"]["main"]
|
2791
|
-
)
|
2792
|
-
if len(local_list_response_user_auth_provider) != 1:
|
2793
|
-
output_content = get_api_output_in_standard_format(
|
2794
|
-
message=messages["INCORRECT_AUTH_PROVIDER"],
|
2795
|
-
log=f"user_id: {user_id} does not have {AuthProviderEnum.SELF.value} auth provider.",
|
2796
|
-
)
|
2797
|
-
raise HTTPException(
|
2798
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
2799
|
-
detail=output_content,
|
2800
|
-
)
|
2801
|
-
# check if user has recovery method enabled
|
2802
|
-
local_list_response_user_recovery_methods = global_object_square_database_helper.get_rows_v0(
|
2803
|
-
database_name=global_string_database_name,
|
2804
|
-
schema_name=global_string_schema_name,
|
2805
|
-
table_name=UserRecoveryMethod.__tablename__,
|
2806
|
-
filters=FiltersV0(
|
2807
|
-
root={
|
2808
|
-
UserRecoveryMethod.user_id.name: FilterConditionsV0(eq=user_id),
|
2809
|
-
UserRecoveryMethod.user_recovery_method_name.name: FilterConditionsV0(
|
2810
|
-
eq=RecoveryMethodEnum.EMAIL.value
|
2811
|
-
),
|
2812
|
-
}
|
2813
|
-
),
|
2814
|
-
)[
|
2815
|
-
"data"
|
2816
|
-
][
|
2817
|
-
"main"
|
2818
|
-
]
|
2819
|
-
if len(local_list_response_user_recovery_methods) != 1:
|
2820
|
-
output_content = get_api_output_in_standard_format(
|
2821
|
-
message=messages["RECOVERY_METHOD_NOT_ENABLED"],
|
2822
|
-
log=f"user_id: {user_id} does not have email recovery method enabled.",
|
2823
|
-
)
|
2824
|
-
raise HTTPException(
|
2825
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
2826
|
-
detail=output_content,
|
2827
|
-
)
|
2828
|
-
# validate if user has email in profile
|
2829
|
-
user_profile_response = global_object_square_database_helper.get_rows_v0(
|
2830
|
-
database_name=global_string_database_name,
|
2831
|
-
schema_name=global_string_schema_name,
|
2832
|
-
table_name=UserProfile.__tablename__,
|
2833
|
-
filters=FiltersV0(
|
2834
|
-
root={UserProfile.user_id.name: FilterConditionsV0(eq=user_id)}
|
2835
|
-
),
|
2836
|
-
apply_filters=True,
|
2837
|
-
)
|
2838
|
-
user_profile_data = user_profile_response["data"]["main"][0]
|
2839
|
-
if not user_profile_data.get(UserProfile.user_profile_email.name):
|
2840
|
-
output_content = get_api_output_in_standard_format(
|
2841
|
-
message=messages["GENERIC_MISSING_REQUIRED_FIELD"],
|
2842
|
-
log="email is required to send verification email.",
|
2843
|
-
)
|
2844
|
-
raise HTTPException(
|
2845
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
2846
|
-
detail=output_content,
|
2847
|
-
)
|
2848
|
-
# check if email is not verified
|
2849
|
-
if not user_profile_data.get(UserProfile.user_profile_email_verified.name):
|
2850
|
-
output_content = get_api_output_in_standard_format(
|
2851
|
-
message=messages["EMAIL_NOT_VERIFIED"],
|
2852
|
-
log="email is not verified.",
|
2853
|
-
)
|
2854
|
-
return JSONResponse(status_code=status.HTTP_200_OK, content=output_content)
|
2855
|
-
# check if reset password code already exists
|
2856
|
-
local_list_response_user_verification_code = global_object_square_database_helper.get_rows_v0(
|
2857
|
-
database_name=global_string_database_name,
|
2858
|
-
schema_name=global_string_schema_name,
|
2859
|
-
table_name=UserVerificationCode.__tablename__,
|
2860
|
-
filters=FiltersV0(
|
2861
|
-
root={
|
2862
|
-
UserVerificationCode.user_id.name: FilterConditionsV0(eq=user_id),
|
2863
|
-
UserVerificationCode.user_verification_code_type.name: FilterConditionsV0(
|
2864
|
-
eq=VerificationCodeTypeEnum.EMAIL_RECOVERY.value
|
2865
|
-
),
|
2866
|
-
UserVerificationCode.user_verification_code_used_at.name: FilterConditionsV0(
|
2867
|
-
is_null=True
|
2868
|
-
),
|
2869
|
-
UserVerificationCode.user_verification_code_expires_at.name: FilterConditionsV0(
|
2870
|
-
gte=datetime.now(timezone.utc).strftime(
|
2871
|
-
"%Y-%m-%d %H:%M:%S.%f+00"
|
2872
|
-
)
|
2873
|
-
),
|
2874
|
-
}
|
2875
|
-
),
|
2876
|
-
order_by=[
|
2877
|
-
"-" + UserVerificationCode.user_verification_code_created_at.name
|
2878
|
-
],
|
2879
|
-
limit=1,
|
2880
|
-
apply_filters=True,
|
2881
|
-
)[
|
2882
|
-
"data"
|
2883
|
-
][
|
2884
|
-
"main"
|
2885
|
-
]
|
2886
|
-
if len(local_list_response_user_verification_code) > 0:
|
2887
|
-
existing_verification_code_data = (
|
2888
|
-
local_list_response_user_verification_code[0]
|
2889
|
-
)
|
2890
|
-
if (
|
2891
|
-
datetime.now(timezone.utc)
|
2892
|
-
- datetime.fromisoformat(
|
2893
|
-
existing_verification_code_data[
|
2894
|
-
UserVerificationCode.user_verification_code_created_at.name
|
2895
|
-
]
|
2896
|
-
)
|
2897
|
-
).total_seconds() < RESEND_COOL_DOWN_TIME_FOR_EMAIL_PASSWORD_RESET_CODE_IN_SECONDS:
|
2898
|
-
output_content = get_api_output_in_standard_format(
|
2899
|
-
message=messages["GENERIC_400"],
|
2900
|
-
log="verification code already exists and was sent within the cooldown period.",
|
2901
|
-
)
|
2902
|
-
raise HTTPException(
|
2903
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
2904
|
-
detail=output_content,
|
2905
|
-
)
|
2906
|
-
"""
|
2907
|
-
main process
|
2908
|
-
"""
|
2909
|
-
verification_code = random.randint(
|
2910
|
-
10 ** (NUMBER_OF_DIGITS_IN_EMAIL_PASSWORD_RESET_CODE - 1),
|
2911
|
-
10**NUMBER_OF_DIGITS_IN_EMAIL_PASSWORD_RESET_CODE - 1,
|
2912
|
-
)
|
2913
|
-
# hash the verification code
|
2914
|
-
hashed_verification_code = bcrypt.hashpw(
|
2915
|
-
str(verification_code).encode("utf-8"), bcrypt.gensalt()
|
2916
|
-
).decode("utf-8")
|
2917
|
-
expires_at = datetime.now(timezone.utc) + timedelta(
|
2918
|
-
seconds=EXPIRY_TIME_FOR_EMAIL_PASSWORD_RESET_CODE_IN_SECONDS
|
2919
|
-
)
|
2920
|
-
# add verification code to UserVerification code table
|
2921
|
-
global_object_square_database_helper.insert_rows_v0(
|
2922
|
-
database_name=global_string_database_name,
|
2923
|
-
schema_name=global_string_schema_name,
|
2924
|
-
table_name=UserVerificationCode.__tablename__,
|
2925
|
-
data=[
|
2926
|
-
{
|
2927
|
-
UserVerificationCode.user_id.name: user_id,
|
2928
|
-
UserVerificationCode.user_verification_code_type.name: VerificationCodeTypeEnum.EMAIL_RECOVERY.value,
|
2929
|
-
UserVerificationCode.user_verification_code_hash.name: hashed_verification_code,
|
2930
|
-
UserVerificationCode.user_verification_code_expires_at.name: expires_at.strftime(
|
2931
|
-
"%Y-%m-%d %H:%M:%S.%f+00"
|
2932
|
-
),
|
2933
|
-
}
|
2934
|
-
],
|
2935
|
-
)
|
2936
|
-
# send verification email
|
2937
|
-
if (
|
2938
|
-
user_profile_data[UserProfile.user_profile_first_name.name]
|
2939
|
-
and user_profile_data[UserProfile.user_profile_last_name.name]
|
2940
|
-
):
|
2941
|
-
user_to_name = f"{user_profile_data[UserProfile.user_profile_first_name.name]} {user_profile_data[UserProfile.user_profile_last_name.name]}"
|
2942
|
-
elif user_profile_data[UserProfile.user_profile_first_name.name]:
|
2943
|
-
user_to_name = user_profile_data[UserProfile.user_profile_first_name.name]
|
2944
|
-
elif user_profile_data[UserProfile.user_profile_last_name.name]:
|
2945
|
-
user_to_name = user_profile_data[UserProfile.user_profile_last_name.name]
|
2946
|
-
else:
|
2947
|
-
user_to_name = ""
|
2948
|
-
|
2949
|
-
mailgun_response = send_email_using_mailgun(
|
2950
|
-
from_email="auth@thepmsquare.com",
|
2951
|
-
from_name="square_authentication",
|
2952
|
-
to_email=user_profile_data[UserProfile.user_profile_email.name],
|
2953
|
-
to_name=user_to_name,
|
2954
|
-
subject="Password Reset Verification Code",
|
2955
|
-
body=f"Your Password Reset verification code is {verification_code}. It will expire in {EXPIRY_TIME_FOR_EMAIL_PASSWORD_RESET_CODE_IN_SECONDS/60} minutes.",
|
2956
|
-
api_key=MAIL_GUN_API_KEY,
|
2957
|
-
domain_name="thepmsquare.com",
|
2958
|
-
)
|
2959
|
-
# add log for email sending
|
2960
|
-
global_object_square_database_helper.insert_rows_v0(
|
2961
|
-
database_name=global_string_database_name,
|
2962
|
-
schema_name=email_schema_name,
|
2963
|
-
table_name=EmailLog.__tablename__,
|
2964
|
-
data=[
|
2965
|
-
{
|
2966
|
-
EmailLog.user_id.name: user_id,
|
2967
|
-
EmailLog.recipient_email.name: user_profile_data[
|
2968
|
-
UserProfile.user_profile_email.name
|
2969
|
-
],
|
2970
|
-
EmailLog.email_type.name: EmailTypeEnum.VERIFY_EMAIL.value,
|
2971
|
-
EmailLog.status.name: EmailStatusEnum.SENT.value,
|
2972
|
-
EmailLog.third_party_message_id.name: mailgun_response.get("id"),
|
2973
|
-
}
|
2974
|
-
],
|
2975
|
-
)
|
2976
|
-
"""
|
2977
|
-
return value
|
2978
|
-
"""
|
2979
|
-
cooldown_reset_at = datetime.now(timezone.utc) + timedelta(
|
2980
|
-
seconds=EXPIRY_TIME_FOR_EMAIL_PASSWORD_RESET_CODE_IN_SECONDS,
|
2981
|
-
)
|
2982
|
-
|
2983
|
-
output_content = get_api_output_in_standard_format(
|
2984
|
-
data={
|
2985
|
-
"expires_at": expires_at.isoformat(),
|
2986
|
-
"cooldown_reset_at": cooldown_reset_at.isoformat(),
|
2987
|
-
},
|
2988
|
-
message=messages["GENERIC_ACTION_SUCCESSFUL"],
|
2989
|
-
)
|
2990
|
-
return JSONResponse(
|
2991
|
-
status_code=status.HTTP_200_OK,
|
2992
|
-
content=output_content,
|
2993
|
-
)
|
2994
|
-
except HTTPException as http_exception:
|
2995
|
-
global_object_square_logger.logger.error(http_exception, exc_info=True)
|
2996
|
-
return JSONResponse(
|
2997
|
-
status_code=http_exception.status_code, content=http_exception.detail
|
450
|
+
return util_send_reset_password_email_v0(
|
451
|
+
username=username,
|
2998
452
|
)
|
453
|
+
except HTTPException as he:
|
454
|
+
global_object_square_logger.logger.error(he, exc_info=True)
|
455
|
+
return JSONResponse(status_code=he.status_code, content=he.detail)
|
2999
456
|
except Exception as e:
|
3000
|
-
"""
|
3001
|
-
rollback logic
|
3002
|
-
"""
|
3003
457
|
global_object_square_logger.logger.error(e, exc_info=True)
|
3004
458
|
output_content = get_api_output_in_standard_format(
|
3005
|
-
message=messages["GENERIC_500"],
|
3006
|
-
log=str(e),
|
459
|
+
message=messages["GENERIC_500"], log=str(e)
|
3007
460
|
)
|
3008
461
|
return JSONResponse(
|
3009
462
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
@@ -3021,309 +474,20 @@ async def reset_password_and_login_using_reset_email_code_v0(
|
|
3021
474
|
app_id = body.app_id
|
3022
475
|
logout_other_sessions = body.logout_other_sessions
|
3023
476
|
try:
|
3024
|
-
|
3025
|
-
|
3026
|
-
|
3027
|
-
|
3028
|
-
|
3029
|
-
|
3030
|
-
|
3031
|
-
|
3032
|
-
|
3033
|
-
|
3034
|
-
root={User.user_username.name: FilterConditionsV0(eq=username)}
|
3035
|
-
),
|
3036
|
-
)["data"]["main"]
|
3037
|
-
)
|
3038
|
-
if len(local_list_authentication_user_response) != 1:
|
3039
|
-
output_content = get_api_output_in_standard_format(
|
3040
|
-
message=messages["INCORRECT_USERNAME"],
|
3041
|
-
log=f"incorrect username: {username}.",
|
3042
|
-
)
|
3043
|
-
raise HTTPException(
|
3044
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
3045
|
-
detail=output_content,
|
3046
|
-
)
|
3047
|
-
user_id = local_list_authentication_user_response[0][User.user_id.name]
|
3048
|
-
# check if user has SELF auth provider
|
3049
|
-
local_list_response_user_auth_provider = (
|
3050
|
-
global_object_square_database_helper.get_rows_v0(
|
3051
|
-
database_name=global_string_database_name,
|
3052
|
-
schema_name=global_string_schema_name,
|
3053
|
-
table_name=UserAuthProvider.__tablename__,
|
3054
|
-
filters=FiltersV0(
|
3055
|
-
root={
|
3056
|
-
UserAuthProvider.user_id.name: FilterConditionsV0(eq=user_id),
|
3057
|
-
UserAuthProvider.auth_provider.name: FilterConditionsV0(
|
3058
|
-
eq=AuthProviderEnum.SELF.value
|
3059
|
-
),
|
3060
|
-
}
|
3061
|
-
),
|
3062
|
-
)["data"]["main"]
|
3063
|
-
)
|
3064
|
-
if len(local_list_response_user_auth_provider) != 1:
|
3065
|
-
output_content = get_api_output_in_standard_format(
|
3066
|
-
message=messages["INCORRECT_AUTH_PROVIDER"],
|
3067
|
-
log=f"user_id: {user_id} does not have {AuthProviderEnum.SELF.value} auth provider.",
|
3068
|
-
)
|
3069
|
-
raise HTTPException(
|
3070
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
3071
|
-
detail=output_content,
|
3072
|
-
)
|
3073
|
-
# check if user has recovery method enabled
|
3074
|
-
local_list_response_user_recovery_methods = global_object_square_database_helper.get_rows_v0(
|
3075
|
-
database_name=global_string_database_name,
|
3076
|
-
schema_name=global_string_schema_name,
|
3077
|
-
table_name=UserRecoveryMethod.__tablename__,
|
3078
|
-
filters=FiltersV0(
|
3079
|
-
root={
|
3080
|
-
UserRecoveryMethod.user_id.name: FilterConditionsV0(eq=user_id),
|
3081
|
-
UserRecoveryMethod.user_recovery_method_name.name: FilterConditionsV0(
|
3082
|
-
eq=RecoveryMethodEnum.EMAIL.value
|
3083
|
-
),
|
3084
|
-
}
|
3085
|
-
),
|
3086
|
-
)[
|
3087
|
-
"data"
|
3088
|
-
][
|
3089
|
-
"main"
|
3090
|
-
]
|
3091
|
-
if len(local_list_response_user_recovery_methods) != 1:
|
3092
|
-
output_content = get_api_output_in_standard_format(
|
3093
|
-
message=messages["RECOVERY_METHOD_NOT_ENABLED"],
|
3094
|
-
log=f"user_id: {user_id} does not have email recovery method enabled.",
|
3095
|
-
)
|
3096
|
-
raise HTTPException(
|
3097
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
3098
|
-
detail=output_content,
|
3099
|
-
)
|
3100
|
-
# check if user has email in profile
|
3101
|
-
user_profile_response = global_object_square_database_helper.get_rows_v0(
|
3102
|
-
database_name=global_string_database_name,
|
3103
|
-
schema_name=global_string_schema_name,
|
3104
|
-
table_name=UserProfile.__tablename__,
|
3105
|
-
filters=FiltersV0(
|
3106
|
-
root={UserProfile.user_id.name: FilterConditionsV0(eq=user_id)}
|
3107
|
-
),
|
3108
|
-
apply_filters=True,
|
3109
|
-
)
|
3110
|
-
user_profile_data = user_profile_response["data"]["main"][0]
|
3111
|
-
if not user_profile_data.get(UserProfile.user_profile_email.name):
|
3112
|
-
output_content = get_api_output_in_standard_format(
|
3113
|
-
message=messages["GENERIC_MISSING_REQUIRED_FIELD"],
|
3114
|
-
log="user seems to have email recovery method enabled, but does not have email in profile.",
|
3115
|
-
)
|
3116
|
-
raise HTTPException(
|
3117
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
3118
|
-
detail=output_content,
|
3119
|
-
)
|
3120
|
-
# check if email is verified.
|
3121
|
-
if not user_profile_data.get(UserProfile.user_profile_email_verified.name):
|
3122
|
-
output_content = get_api_output_in_standard_format(
|
3123
|
-
message=messages["EMAIL_NOT_VERIFIED"],
|
3124
|
-
log="email is not verified.",
|
3125
|
-
)
|
3126
|
-
return JSONResponse(status_code=status.HTTP_200_OK, content=output_content)
|
3127
|
-
# validate if user is assigned to the app.
|
3128
|
-
# not checking [skipping] if the app exists, as it is not required for this endpoint.
|
3129
|
-
local_list_response_user_app = global_object_square_database_helper.get_rows_v0(
|
3130
|
-
database_name=global_string_database_name,
|
3131
|
-
schema_name=global_string_schema_name,
|
3132
|
-
table_name=UserApp.__tablename__,
|
3133
|
-
filters=FiltersV0(
|
3134
|
-
root={
|
3135
|
-
UserApp.user_id.name: FilterConditionsV0(eq=user_id),
|
3136
|
-
UserApp.app_id.name: FilterConditionsV0(eq=app_id),
|
3137
|
-
}
|
3138
|
-
),
|
3139
|
-
)["data"]["main"]
|
3140
|
-
if len(local_list_response_user_app) == 0:
|
3141
|
-
output_content = get_api_output_in_standard_format(
|
3142
|
-
message=messages["GENERIC_400"],
|
3143
|
-
log=f"user_id: {user_id} is not assigned to app_id: {app_id}.",
|
3144
|
-
)
|
3145
|
-
raise HTTPException(
|
3146
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
3147
|
-
detail=output_content,
|
3148
|
-
)
|
3149
|
-
"""
|
3150
|
-
main process
|
3151
|
-
"""
|
3152
|
-
# validate email reset code
|
3153
|
-
local_list_response_user_verification_code = global_object_square_database_helper.get_rows_v0(
|
3154
|
-
database_name=global_string_database_name,
|
3155
|
-
schema_name=global_string_schema_name,
|
3156
|
-
table_name=UserVerificationCode.__tablename__,
|
3157
|
-
filters=FiltersV0(
|
3158
|
-
root={
|
3159
|
-
UserVerificationCode.user_id.name: FilterConditionsV0(eq=user_id),
|
3160
|
-
UserVerificationCode.user_verification_code_type.name: FilterConditionsV0(
|
3161
|
-
eq=VerificationCodeTypeEnum.EMAIL_RECOVERY.value
|
3162
|
-
),
|
3163
|
-
UserVerificationCode.user_verification_code_expires_at.name: FilterConditionsV0(
|
3164
|
-
gte=datetime.now(timezone.utc).strftime(
|
3165
|
-
"%Y-%m-%d %H:%M:%S.%f+00"
|
3166
|
-
)
|
3167
|
-
),
|
3168
|
-
UserVerificationCode.user_verification_code_used_at.name: FilterConditionsV0(
|
3169
|
-
is_null=True
|
3170
|
-
),
|
3171
|
-
}
|
3172
|
-
),
|
3173
|
-
columns=[UserVerificationCode.user_verification_code_hash.name],
|
3174
|
-
order_by=[
|
3175
|
-
"-" + UserVerificationCode.user_verification_code_created_at.name
|
3176
|
-
],
|
3177
|
-
limit=1,
|
3178
|
-
)[
|
3179
|
-
"data"
|
3180
|
-
][
|
3181
|
-
"main"
|
3182
|
-
]
|
3183
|
-
if len(local_list_response_user_verification_code) != 1:
|
3184
|
-
output_content = get_api_output_in_standard_format(
|
3185
|
-
message=messages["INCORRECT_VERIFICATION_CODE"],
|
3186
|
-
log=f"incorrect reset_email_code: {reset_email_code} for user_id: {user_id}.",
|
3187
|
-
)
|
3188
|
-
raise HTTPException(
|
3189
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
3190
|
-
detail=output_content,
|
3191
|
-
)
|
3192
|
-
latest_hashed_verification_code = local_list_response_user_verification_code[0][
|
3193
|
-
UserVerificationCode.user_verification_code_hash.name
|
3194
|
-
]
|
3195
|
-
|
3196
|
-
if not bcrypt.checkpw(
|
3197
|
-
reset_email_code.encode("utf-8"),
|
3198
|
-
latest_hashed_verification_code.encode("utf-8"),
|
3199
|
-
):
|
3200
|
-
output_content = get_api_output_in_standard_format(
|
3201
|
-
message=messages["INCORRECT_VERIFICATION_CODE"],
|
3202
|
-
log=f"incorrect reset_email_code: {reset_email_code} for user_id: {user_id}.",
|
3203
|
-
)
|
3204
|
-
raise HTTPException(
|
3205
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
3206
|
-
detail=output_content,
|
3207
|
-
)
|
3208
|
-
|
3209
|
-
# hash the new password
|
3210
|
-
local_str_hashed_password = bcrypt.hashpw(
|
3211
|
-
new_password.encode("utf-8"), bcrypt.gensalt()
|
3212
|
-
).decode("utf-8")
|
3213
|
-
# update the password
|
3214
|
-
global_object_square_database_helper.edit_rows_v0(
|
3215
|
-
database_name=global_string_database_name,
|
3216
|
-
schema_name=global_string_schema_name,
|
3217
|
-
table_name=UserCredential.__tablename__,
|
3218
|
-
filters=FiltersV0(
|
3219
|
-
root={
|
3220
|
-
UserCredential.user_id.name: FilterConditionsV0(eq=user_id),
|
3221
|
-
}
|
3222
|
-
),
|
3223
|
-
data={
|
3224
|
-
UserCredential.user_credential_hashed_password.name: local_str_hashed_password,
|
3225
|
-
},
|
3226
|
-
)
|
3227
|
-
# mark the email code as used
|
3228
|
-
global_object_square_database_helper.edit_rows_v0(
|
3229
|
-
database_name=global_string_database_name,
|
3230
|
-
schema_name=global_string_schema_name,
|
3231
|
-
table_name=UserVerificationCode.__tablename__,
|
3232
|
-
filters=FiltersV0(
|
3233
|
-
root={
|
3234
|
-
UserVerificationCode.user_id.name: FilterConditionsV0(eq=user_id),
|
3235
|
-
UserVerificationCode.user_verification_code_type.name: FilterConditionsV0(
|
3236
|
-
eq=VerificationCodeTypeEnum.EMAIL_RECOVERY.value
|
3237
|
-
),
|
3238
|
-
UserVerificationCode.user_verification_code_hash.name: FilterConditionsV0(
|
3239
|
-
eq=latest_hashed_verification_code
|
3240
|
-
),
|
3241
|
-
}
|
3242
|
-
),
|
3243
|
-
data={
|
3244
|
-
UserVerificationCode.user_verification_code_used_at.name: datetime.now(
|
3245
|
-
timezone.utc
|
3246
|
-
).strftime("%Y-%m-%d %H:%M:%S.%f+00"),
|
3247
|
-
},
|
3248
|
-
)
|
3249
|
-
if logout_other_sessions:
|
3250
|
-
# delete all sessions for user
|
3251
|
-
global_object_square_database_helper.delete_rows_v0(
|
3252
|
-
database_name=global_string_database_name,
|
3253
|
-
schema_name=global_string_schema_name,
|
3254
|
-
table_name=UserSession.__tablename__,
|
3255
|
-
filters=FiltersV0(
|
3256
|
-
root={
|
3257
|
-
UserSession.user_id.name: FilterConditionsV0(eq=user_id),
|
3258
|
-
}
|
3259
|
-
),
|
3260
|
-
)
|
3261
|
-
# generate access token and refresh token
|
3262
|
-
local_dict_access_token_payload = {
|
3263
|
-
"app_id": app_id,
|
3264
|
-
"user_id": user_id,
|
3265
|
-
"exp": datetime.now(timezone.utc)
|
3266
|
-
+ timedelta(minutes=config_int_access_token_valid_minutes),
|
3267
|
-
}
|
3268
|
-
local_str_access_token = jwt.encode(
|
3269
|
-
local_dict_access_token_payload, config_str_secret_key_for_access_token
|
3270
|
-
)
|
3271
|
-
local_object_refresh_token_expiry_time = datetime.now(timezone.utc) + timedelta(
|
3272
|
-
minutes=config_int_refresh_token_valid_minutes
|
3273
|
-
)
|
3274
|
-
local_dict_refresh_token_payload = {
|
3275
|
-
"app_id": app_id,
|
3276
|
-
"user_id": user_id,
|
3277
|
-
"exp": local_object_refresh_token_expiry_time,
|
3278
|
-
}
|
3279
|
-
local_str_refresh_token = jwt.encode(
|
3280
|
-
local_dict_refresh_token_payload, config_str_secret_key_for_refresh_token
|
3281
|
-
)
|
3282
|
-
# insert the refresh token in the database
|
3283
|
-
global_object_square_database_helper.insert_rows_v0(
|
3284
|
-
database_name=global_string_database_name,
|
3285
|
-
schema_name=global_string_schema_name,
|
3286
|
-
table_name=UserSession.__tablename__,
|
3287
|
-
data=[
|
3288
|
-
{
|
3289
|
-
UserSession.user_id.name: user_id,
|
3290
|
-
UserSession.app_id.name: app_id,
|
3291
|
-
UserSession.user_session_refresh_token.name: local_str_refresh_token,
|
3292
|
-
UserSession.user_session_expiry_time.name: local_object_refresh_token_expiry_time.strftime(
|
3293
|
-
"%Y-%m-%d %H:%M:%S.%f+00"
|
3294
|
-
),
|
3295
|
-
}
|
3296
|
-
],
|
3297
|
-
)
|
3298
|
-
"""
|
3299
|
-
return value
|
3300
|
-
"""
|
3301
|
-
output_content = get_api_output_in_standard_format(
|
3302
|
-
message=messages["GENERIC_ACTION_SUCCESSFUL"],
|
3303
|
-
data={
|
3304
|
-
"main": {
|
3305
|
-
"user_id": user_id,
|
3306
|
-
"access_token": local_str_access_token,
|
3307
|
-
"refresh_token": local_str_refresh_token,
|
3308
|
-
"refresh_token_expiry_time": local_object_refresh_token_expiry_time.isoformat(),
|
3309
|
-
}
|
3310
|
-
},
|
3311
|
-
)
|
3312
|
-
|
3313
|
-
return JSONResponse(status_code=status.HTTP_200_OK, content=output_content)
|
3314
|
-
except HTTPException as http_exception:
|
3315
|
-
global_object_square_logger.logger.error(http_exception, exc_info=True)
|
3316
|
-
return JSONResponse(
|
3317
|
-
status_code=http_exception.status_code, content=http_exception.detail
|
3318
|
-
)
|
477
|
+
return util_reset_password_and_login_using_reset_email_code_v0(
|
478
|
+
reset_email_code=reset_email_code,
|
479
|
+
username=username,
|
480
|
+
new_password=new_password,
|
481
|
+
app_id=app_id,
|
482
|
+
logout_other_sessions=logout_other_sessions,
|
483
|
+
)
|
484
|
+
except HTTPException as he:
|
485
|
+
global_object_square_logger.logger.error(he, exc_info=True)
|
486
|
+
return JSONResponse(status_code=he.status_code, content=he.detail)
|
3319
487
|
except Exception as e:
|
3320
|
-
"""
|
3321
|
-
rollback logic
|
3322
|
-
"""
|
3323
488
|
global_object_square_logger.logger.error(e, exc_info=True)
|
3324
489
|
output_content = get_api_output_in_standard_format(
|
3325
|
-
message=messages["GENERIC_500"],
|
3326
|
-
log=str(e),
|
490
|
+
message=messages["GENERIC_500"], log=str(e)
|
3327
491
|
)
|
3328
492
|
return JSONResponse(
|
3329
493
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|