square-authentication 1.0.0__py3-none-any.whl → 3.0.0__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/configuration.py +5 -5
- square_authentication/main.py +4 -4
- square_authentication/messages.py +17 -0
- square_authentication/pydantic_models/__init__.py +0 -0
- square_authentication/pydantic_models/core.py +24 -0
- square_authentication/routes/core.py +990 -284
- square_authentication/routes/utility.py +3 -1
- square_authentication-3.0.0.dist-info/METADATA +79 -0
- square_authentication-3.0.0.dist-info/RECORD +17 -0
- square_authentication-1.0.0.dist-info/METADATA +0 -51
- square_authentication-1.0.0.dist-info/RECORD +0 -14
- {square_authentication-1.0.0.dist-info → square_authentication-3.0.0.dist-info}/WHEEL +0 -0
- {square_authentication-1.0.0.dist-info → square_authentication-3.0.0.dist-info}/top_level.txt +0 -0
@@ -1,22 +1,28 @@
|
|
1
1
|
from datetime import datetime, timedelta, timezone
|
2
|
-
from typing import Annotated,
|
2
|
+
from typing import Annotated, List
|
3
3
|
|
4
4
|
import bcrypt
|
5
5
|
import jwt
|
6
|
-
from fastapi import APIRouter, status, Header
|
6
|
+
from fastapi import APIRouter, status, Header, HTTPException
|
7
7
|
from fastapi.responses import JSONResponse
|
8
|
-
from
|
8
|
+
from square_commons import get_api_output_in_standard_format
|
9
|
+
from square_database.pydantic_models.pydantic_models import (
|
10
|
+
FiltersV0,
|
11
|
+
FilterConditionsV0,
|
12
|
+
)
|
9
13
|
from square_database_helper.main import SquareDatabaseHelper
|
10
|
-
from square_database_structure.square
|
14
|
+
from square_database_structure.square import global_string_database_name
|
15
|
+
from square_database_structure.square.authentication import global_string_schema_name
|
11
16
|
from square_database_structure.square.authentication.tables import (
|
12
|
-
local_string_database_name,
|
13
|
-
local_string_schema_name,
|
14
17
|
User,
|
15
|
-
UserLog,
|
16
18
|
UserCredential,
|
17
|
-
UserProfile,
|
18
19
|
UserSession,
|
20
|
+
UserApp,
|
21
|
+
)
|
22
|
+
from square_database_structure.square.public import (
|
23
|
+
global_string_schema_name as global_string_public_schema_name,
|
19
24
|
)
|
25
|
+
from square_database_structure.square.public.tables import App
|
20
26
|
|
21
27
|
from square_authentication.configuration import (
|
22
28
|
global_object_square_logger,
|
@@ -28,6 +34,13 @@ from square_authentication.configuration import (
|
|
28
34
|
config_int_square_database_port,
|
29
35
|
config_str_square_database_protocol,
|
30
36
|
)
|
37
|
+
from square_authentication.messages import messages
|
38
|
+
from square_authentication.pydantic_models.core import (
|
39
|
+
RegisterUsernameV0,
|
40
|
+
LoginUsernameV0,
|
41
|
+
DeleteUserV0,
|
42
|
+
UpdatePasswordV0,
|
43
|
+
)
|
31
44
|
from square_authentication.utils.token import get_jwt_payload
|
32
45
|
|
33
46
|
router = APIRouter(
|
@@ -41,66 +54,541 @@ global_object_square_database_helper = SquareDatabaseHelper(
|
|
41
54
|
)
|
42
55
|
|
43
56
|
|
44
|
-
@router.
|
57
|
+
@router.post("/register_username/v0")
|
45
58
|
@global_object_square_logger.async_auto_logger
|
46
|
-
async def
|
59
|
+
async def register_username_v0(
|
60
|
+
body: RegisterUsernameV0,
|
61
|
+
):
|
62
|
+
username = body.username
|
63
|
+
password = body.password
|
64
|
+
app_id = body.app_id
|
65
|
+
|
47
66
|
local_str_user_id = None
|
67
|
+
local_str_access_token = None
|
68
|
+
local_str_refresh_token = None
|
69
|
+
|
70
|
+
username = username.lower()
|
48
71
|
try:
|
49
|
-
|
72
|
+
"""
|
73
|
+
validation
|
74
|
+
"""
|
75
|
+
|
76
|
+
# validation for username
|
77
|
+
local_list_response_user_creds = global_object_square_database_helper.get_rows_v0(
|
78
|
+
database_name=global_string_database_name,
|
79
|
+
schema_name=global_string_schema_name,
|
80
|
+
table_name=UserCredential.__tablename__,
|
81
|
+
filters=FiltersV0(
|
82
|
+
{
|
83
|
+
UserCredential.user_credential_username.name: FilterConditionsV0(
|
84
|
+
eq=username
|
85
|
+
)
|
86
|
+
}
|
87
|
+
),
|
88
|
+
)[
|
89
|
+
"data"
|
90
|
+
][
|
91
|
+
"main"
|
92
|
+
]
|
93
|
+
if len(local_list_response_user_creds) > 0:
|
94
|
+
output_content = get_api_output_in_standard_format(
|
95
|
+
message=messages["USERNAME_ALREADY_EXISTS"],
|
96
|
+
log=f"an account with the username {username} already exists.",
|
97
|
+
)
|
98
|
+
raise HTTPException(
|
99
|
+
status_code=status.HTTP_409_CONFLICT,
|
100
|
+
detail=output_content,
|
101
|
+
)
|
102
|
+
|
103
|
+
"""
|
104
|
+
main process
|
105
|
+
"""
|
50
106
|
# entry in user table
|
51
|
-
local_list_response_user = global_object_square_database_helper.
|
107
|
+
local_list_response_user = global_object_square_database_helper.insert_rows_v0(
|
52
108
|
data=[{}],
|
53
|
-
database_name=
|
54
|
-
schema_name=
|
109
|
+
database_name=global_string_database_name,
|
110
|
+
schema_name=global_string_schema_name,
|
55
111
|
table_name=User.__tablename__,
|
56
|
-
)
|
112
|
+
)["data"]["main"]
|
57
113
|
local_str_user_id = local_list_response_user[0][User.user_id.name]
|
58
|
-
# ======================================================================================
|
59
114
|
|
60
|
-
#
|
61
|
-
|
62
|
-
|
115
|
+
# entry in credential table
|
116
|
+
|
117
|
+
# hash password
|
118
|
+
local_str_hashed_password = bcrypt.hashpw(
|
119
|
+
password.encode("utf-8"), bcrypt.gensalt()
|
120
|
+
).decode("utf-8")
|
121
|
+
|
122
|
+
global_object_square_database_helper.insert_rows_v0(
|
63
123
|
data=[
|
64
124
|
{
|
65
|
-
|
66
|
-
|
125
|
+
UserCredential.user_id.name: local_str_user_id,
|
126
|
+
UserCredential.user_credential_username.name: username,
|
127
|
+
UserCredential.user_credential_hashed_password.name: local_str_hashed_password,
|
67
128
|
}
|
68
129
|
],
|
69
|
-
database_name=
|
70
|
-
schema_name=
|
71
|
-
table_name=
|
130
|
+
database_name=global_string_database_name,
|
131
|
+
schema_name=global_string_schema_name,
|
132
|
+
table_name=UserCredential.__tablename__,
|
72
133
|
)
|
73
|
-
|
134
|
+
if app_id is not None:
|
135
|
+
# assign app to user
|
136
|
+
global_object_square_database_helper.insert_rows_v0(
|
137
|
+
database_name=global_string_database_name,
|
138
|
+
schema_name=global_string_schema_name,
|
139
|
+
table_name=UserApp.__tablename__,
|
140
|
+
data=[
|
141
|
+
{
|
142
|
+
UserApp.user_id.name: local_str_user_id,
|
143
|
+
UserApp.app_id.name: app_id,
|
144
|
+
}
|
145
|
+
],
|
146
|
+
)
|
74
147
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
148
|
+
# return new access token and refresh token
|
149
|
+
# create access token
|
150
|
+
local_dict_access_token_payload = {
|
151
|
+
"app_id": app_id,
|
152
|
+
"user_id": local_str_user_id,
|
153
|
+
"exp": datetime.now(timezone.utc)
|
154
|
+
+ timedelta(minutes=config_int_access_token_valid_minutes),
|
155
|
+
}
|
156
|
+
local_str_access_token = jwt.encode(
|
157
|
+
local_dict_access_token_payload,
|
158
|
+
config_str_secret_key_for_access_token,
|
159
|
+
)
|
160
|
+
|
161
|
+
# create refresh token
|
162
|
+
local_object_refresh_token_expiry_time = datetime.now(
|
163
|
+
timezone.utc
|
164
|
+
) + timedelta(minutes=config_int_refresh_token_valid_minutes)
|
165
|
+
|
166
|
+
local_dict_refresh_token_payload = {
|
167
|
+
"app_id": app_id,
|
168
|
+
"user_id": local_str_user_id,
|
169
|
+
"exp": local_object_refresh_token_expiry_time,
|
170
|
+
}
|
171
|
+
local_str_refresh_token = jwt.encode(
|
172
|
+
local_dict_refresh_token_payload,
|
173
|
+
config_str_secret_key_for_refresh_token,
|
174
|
+
)
|
175
|
+
# entry in user session table
|
176
|
+
global_object_square_database_helper.insert_rows_v0(
|
177
|
+
data=[
|
178
|
+
{
|
179
|
+
UserSession.user_id.name: local_str_user_id,
|
180
|
+
UserSession.app_id.name: app_id,
|
181
|
+
UserSession.user_session_refresh_token.name: local_str_refresh_token,
|
182
|
+
UserSession.user_session_expiry_time.name: local_object_refresh_token_expiry_time.strftime(
|
183
|
+
"%Y-%m-%d %H:%M:%S.%f+00"
|
184
|
+
),
|
185
|
+
}
|
186
|
+
],
|
187
|
+
database_name=global_string_database_name,
|
188
|
+
schema_name=global_string_schema_name,
|
189
|
+
table_name=UserSession.__tablename__,
|
190
|
+
)
|
191
|
+
"""
|
192
|
+
return value
|
193
|
+
"""
|
194
|
+
output_content = get_api_output_in_standard_format(
|
195
|
+
message=messages["REGISTRATION_SUCCESSFUL"],
|
196
|
+
data={
|
197
|
+
"main": {
|
198
|
+
"user_id": local_str_user_id,
|
199
|
+
"username": username,
|
200
|
+
"app_id": app_id,
|
201
|
+
"access_token": local_str_access_token,
|
202
|
+
"refresh_token": local_str_refresh_token,
|
203
|
+
},
|
204
|
+
},
|
205
|
+
)
|
206
|
+
return JSONResponse(
|
207
|
+
status_code=status.HTTP_201_CREATED,
|
208
|
+
content=output_content,
|
209
|
+
)
|
210
|
+
except HTTPException as http_exception:
|
211
|
+
return JSONResponse(
|
212
|
+
status_code=http_exception.status_code, content=http_exception.detail
|
213
|
+
)
|
214
|
+
except Exception as e:
|
215
|
+
global_object_square_logger.logger.error(e, exc_info=True)
|
216
|
+
"""
|
217
|
+
rollback logic
|
218
|
+
"""
|
219
|
+
if local_str_user_id:
|
220
|
+
global_object_square_database_helper.delete_rows_v0(
|
221
|
+
database_name=global_string_database_name,
|
222
|
+
schema_name=global_string_schema_name,
|
223
|
+
table_name=User.__tablename__,
|
224
|
+
filters=FiltersV0(
|
225
|
+
{User.user_id.name: FilterConditionsV0(eq=local_str_user_id)}
|
226
|
+
),
|
83
227
|
)
|
228
|
+
output_content = get_api_output_in_standard_format(
|
229
|
+
message=messages["GENERIC_500"],
|
230
|
+
log=str(e),
|
231
|
+
)
|
232
|
+
return JSONResponse(
|
233
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
84
234
|
)
|
85
235
|
|
86
|
-
# ======================================================================================
|
87
236
|
|
88
|
-
|
89
|
-
|
237
|
+
@router.get("/get_user_details/v0")
|
238
|
+
@global_object_square_logger.async_auto_logger
|
239
|
+
async def get_user_details_v0(
|
240
|
+
access_token: Annotated[str, Header()],
|
241
|
+
):
|
242
|
+
try:
|
243
|
+
"""
|
244
|
+
validation
|
245
|
+
"""
|
246
|
+
# validate access token
|
247
|
+
try:
|
248
|
+
local_dict_access_token_payload = get_jwt_payload(
|
249
|
+
access_token, config_str_secret_key_for_access_token
|
250
|
+
)
|
251
|
+
except Exception as error:
|
252
|
+
output_content = get_api_output_in_standard_format(
|
253
|
+
message=messages["INCORRECT_ACCESS_TOKEN"], log=str(error)
|
254
|
+
)
|
255
|
+
return JSONResponse(
|
256
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
257
|
+
content=output_content,
|
258
|
+
)
|
259
|
+
user_id = local_dict_access_token_payload["user_id"]
|
260
|
+
"""
|
261
|
+
main process
|
262
|
+
"""
|
263
|
+
local_list_response_user_app = global_object_square_database_helper.get_rows_v0(
|
264
|
+
database_name=global_string_database_name,
|
265
|
+
schema_name=global_string_schema_name,
|
266
|
+
table_name=UserApp.__tablename__,
|
267
|
+
filters=FiltersV0({UserApp.user_id.name: FilterConditionsV0(eq=user_id)}),
|
268
|
+
)["data"]["main"]
|
269
|
+
local_list_response_user_credentials = (
|
270
|
+
global_object_square_database_helper.get_rows_v0(
|
271
|
+
database_name=global_string_database_name,
|
272
|
+
schema_name=global_string_schema_name,
|
273
|
+
table_name=UserCredential.__tablename__,
|
274
|
+
filters=FiltersV0(
|
275
|
+
{UserCredential.user_id.name: FilterConditionsV0(eq=user_id)}
|
276
|
+
),
|
277
|
+
)["data"]["main"]
|
278
|
+
)
|
279
|
+
# not putting filter for expiry refresh tokens
|
280
|
+
local_list_response_user_sessions = (
|
281
|
+
global_object_square_database_helper.get_rows_v0(
|
282
|
+
database_name=global_string_database_name,
|
283
|
+
schema_name=global_string_schema_name,
|
284
|
+
table_name=UserSession.__tablename__,
|
285
|
+
filters=FiltersV0(
|
286
|
+
{
|
287
|
+
UserSession.user_id.name: FilterConditionsV0(eq=user_id),
|
288
|
+
}
|
289
|
+
),
|
290
|
+
)["data"]["main"]
|
291
|
+
)
|
292
|
+
"""
|
293
|
+
return value
|
294
|
+
"""
|
295
|
+
return_this = {
|
296
|
+
"user_id": user_id,
|
297
|
+
"credentials": {
|
298
|
+
"username": local_list_response_user_credentials[0][
|
299
|
+
UserCredential.user_credential_username.name
|
300
|
+
],
|
301
|
+
},
|
302
|
+
"apps": [x[UserApp.app_id.name] for x in local_list_response_user_app],
|
303
|
+
"sessions": [
|
304
|
+
{
|
305
|
+
"app_id": x[UserApp.app_id.name],
|
306
|
+
"sessions": len(
|
307
|
+
[
|
308
|
+
y
|
309
|
+
for y in local_list_response_user_sessions
|
310
|
+
if y[UserSession.app_id.name] == x[UserApp.app_id.name]
|
311
|
+
]
|
312
|
+
),
|
313
|
+
}
|
314
|
+
for x in local_list_response_user_app
|
315
|
+
],
|
316
|
+
}
|
317
|
+
output_content = get_api_output_in_standard_format(
|
318
|
+
message=messages["GENERIC_READ_SUCCESSFUL"],
|
319
|
+
data={"main": return_this},
|
320
|
+
)
|
321
|
+
return JSONResponse(
|
322
|
+
status_code=status.HTTP_200_OK,
|
323
|
+
content=output_content,
|
324
|
+
)
|
325
|
+
except HTTPException as http_exception:
|
326
|
+
return JSONResponse(
|
327
|
+
status_code=http_exception.status_code, content=http_exception.detail
|
328
|
+
)
|
329
|
+
except Exception as e:
|
330
|
+
"""
|
331
|
+
rollback logic
|
332
|
+
"""
|
333
|
+
global_object_square_logger.logger.error(e, exc_info=True)
|
334
|
+
output_content = get_api_output_in_standard_format(
|
335
|
+
message=messages["GENERIC_500"],
|
336
|
+
log=str(e),
|
337
|
+
)
|
338
|
+
return JSONResponse(
|
339
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
340
|
+
content=output_content,
|
341
|
+
)
|
90
342
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
343
|
+
|
344
|
+
@router.patch("/update_user_app_ids/v0")
|
345
|
+
@global_object_square_logger.async_auto_logger
|
346
|
+
async def update_user_app_ids_v0(
|
347
|
+
access_token: Annotated[str, Header()],
|
348
|
+
app_ids_to_add: List[int],
|
349
|
+
app_ids_to_remove: List[int],
|
350
|
+
):
|
351
|
+
try:
|
352
|
+
|
353
|
+
"""
|
354
|
+
validation
|
355
|
+
"""
|
356
|
+
# validate access token
|
357
|
+
try:
|
358
|
+
local_dict_access_token_payload = get_jwt_payload(
|
359
|
+
access_token, config_str_secret_key_for_access_token
|
360
|
+
)
|
361
|
+
except Exception as error:
|
362
|
+
output_content = get_api_output_in_standard_format(
|
363
|
+
message=messages["INCORRECT_ACCESS_TOKEN"], log=str(error)
|
364
|
+
)
|
365
|
+
return JSONResponse(
|
366
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
367
|
+
content=output_content,
|
368
|
+
)
|
369
|
+
user_id = local_dict_access_token_payload["user_id"]
|
370
|
+
|
371
|
+
app_ids_to_add = list(set(app_ids_to_add))
|
372
|
+
app_ids_to_remove = list(set(app_ids_to_remove))
|
373
|
+
|
374
|
+
# check if app_ids_to_add and app_ids_to_remove don't have common ids.
|
375
|
+
local_list_common_app_ids = set(app_ids_to_add) & set(app_ids_to_remove)
|
376
|
+
if len(local_list_common_app_ids) > 0:
|
377
|
+
output_content = get_api_output_in_standard_format(
|
378
|
+
message=messages["GENERIC_400"],
|
379
|
+
log=f"invalid app_ids: {list(local_list_common_app_ids)}, present in both add list and remove list.",
|
380
|
+
)
|
381
|
+
raise HTTPException(
|
382
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
383
|
+
detail=output_content,
|
384
|
+
)
|
385
|
+
|
386
|
+
# check if all app_ids are valid
|
387
|
+
local_list_all_app_ids = [*app_ids_to_add, *app_ids_to_remove]
|
388
|
+
local_list_response_app = global_object_square_database_helper.get_rows_v0(
|
389
|
+
database_name=global_string_database_name,
|
390
|
+
schema_name=global_string_public_schema_name,
|
391
|
+
table_name=App.__tablename__,
|
392
|
+
apply_filters=False,
|
393
|
+
filters=FiltersV0({}),
|
394
|
+
)["data"]["main"]
|
395
|
+
local_list_invalid_ids = [
|
396
|
+
x
|
397
|
+
for x in local_list_all_app_ids
|
398
|
+
if x not in [y[App.app_id.name] for y in local_list_response_app]
|
399
|
+
]
|
400
|
+
if len(local_list_invalid_ids) > 0:
|
401
|
+
output_content = get_api_output_in_standard_format(
|
402
|
+
message=messages["GENERIC_400"],
|
403
|
+
log=f"invalid app_ids: {local_list_invalid_ids}.",
|
404
|
+
)
|
405
|
+
raise HTTPException(
|
406
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
407
|
+
detail=output_content,
|
408
|
+
)
|
409
|
+
"""
|
410
|
+
main process
|
411
|
+
"""
|
412
|
+
# logic for adding new app_ids
|
413
|
+
local_list_response_user_app = global_object_square_database_helper.get_rows_v0(
|
414
|
+
database_name=global_string_database_name,
|
415
|
+
schema_name=global_string_schema_name,
|
416
|
+
table_name=UserApp.__tablename__,
|
417
|
+
filters=FiltersV0({UserApp.user_id.name: FilterConditionsV0(eq=user_id)}),
|
418
|
+
)["data"]["main"]
|
419
|
+
local_list_new_app_ids = [
|
420
|
+
{
|
421
|
+
UserApp.user_id.name: user_id,
|
422
|
+
UserApp.app_id.name: x,
|
423
|
+
}
|
424
|
+
for x in app_ids_to_add
|
425
|
+
if x not in [y[UserApp.app_id.name] for y in local_list_response_user_app]
|
426
|
+
]
|
427
|
+
if len(local_list_new_app_ids) > 0:
|
428
|
+
global_object_square_database_helper.insert_rows_v0(
|
429
|
+
database_name=global_string_database_name,
|
430
|
+
schema_name=global_string_schema_name,
|
431
|
+
table_name=UserApp.__tablename__,
|
432
|
+
data=local_list_new_app_ids,
|
433
|
+
)
|
434
|
+
|
435
|
+
# logic for removing app_ids
|
436
|
+
for app_id in app_ids_to_remove:
|
437
|
+
global_object_square_database_helper.delete_rows_v0(
|
438
|
+
database_name=global_string_database_name,
|
439
|
+
schema_name=global_string_schema_name,
|
440
|
+
table_name=UserApp.__tablename__,
|
441
|
+
filters=FiltersV0(
|
442
|
+
{
|
443
|
+
UserApp.user_id.name: FilterConditionsV0(eq=user_id),
|
444
|
+
UserApp.app_id.name: FilterConditionsV0(eq=app_id),
|
445
|
+
}
|
446
|
+
),
|
447
|
+
)
|
448
|
+
# logout user from removed apps
|
449
|
+
global_object_square_database_helper.delete_rows_v0(
|
450
|
+
database_name=global_string_database_name,
|
451
|
+
schema_name=global_string_schema_name,
|
452
|
+
table_name=UserSession.__tablename__,
|
453
|
+
filters=FiltersV0(
|
454
|
+
{
|
455
|
+
UserSession.user_id.name: FilterConditionsV0(eq=user_id),
|
456
|
+
UserSession.app_id.name: FilterConditionsV0(eq=app_id),
|
457
|
+
}
|
458
|
+
),
|
459
|
+
)
|
460
|
+
|
461
|
+
"""
|
462
|
+
return value
|
463
|
+
"""
|
464
|
+
# get latest app ids
|
465
|
+
local_list_response_user_app = global_object_square_database_helper.get_rows_v0(
|
466
|
+
database_name=global_string_database_name,
|
467
|
+
schema_name=global_string_schema_name,
|
468
|
+
table_name=UserApp.__tablename__,
|
469
|
+
filters=FiltersV0({UserApp.user_id.name: FilterConditionsV0(eq=user_id)}),
|
470
|
+
)["data"]["main"]
|
471
|
+
output_content = get_api_output_in_standard_format(
|
472
|
+
message=messages["GENERIC_UPDATE_SUCCESSFUL"],
|
473
|
+
data={
|
474
|
+
"main": [x[UserApp.app_id.name] for x in local_list_response_user_app]
|
475
|
+
},
|
476
|
+
)
|
477
|
+
return JSONResponse(
|
478
|
+
status_code=status.HTTP_200_OK,
|
479
|
+
content=output_content,
|
480
|
+
)
|
481
|
+
except HTTPException as http_exception:
|
482
|
+
return JSONResponse(
|
483
|
+
status_code=http_exception.status_code, content=http_exception.detail
|
484
|
+
)
|
485
|
+
except Exception as e:
|
486
|
+
"""
|
487
|
+
rollback logic
|
488
|
+
"""
|
489
|
+
global_object_square_logger.logger.error(e, exc_info=True)
|
490
|
+
output_content = get_api_output_in_standard_format(
|
491
|
+
message=messages["GENERIC_500"],
|
492
|
+
log=str(e),
|
493
|
+
)
|
494
|
+
return JSONResponse(
|
495
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
496
|
+
content=output_content,
|
497
|
+
)
|
498
|
+
|
499
|
+
|
500
|
+
@router.get("/login_username/v0")
|
501
|
+
@global_object_square_logger.async_auto_logger
|
502
|
+
async def login_username_v0(body: LoginUsernameV0):
|
503
|
+
username = body.username
|
504
|
+
password = body.password
|
505
|
+
app_id = body.app_id
|
506
|
+
username = username.lower()
|
507
|
+
try:
|
508
|
+
"""
|
509
|
+
validation
|
510
|
+
"""
|
511
|
+
# validation for username
|
512
|
+
local_list_authentication_user_response = global_object_square_database_helper.get_rows_v0(
|
513
|
+
database_name=global_string_database_name,
|
514
|
+
schema_name=global_string_schema_name,
|
515
|
+
table_name=UserCredential.__tablename__,
|
516
|
+
filters=FiltersV0(
|
517
|
+
{
|
518
|
+
UserCredential.user_credential_username.name: FilterConditionsV0(
|
519
|
+
eq=username
|
520
|
+
)
|
521
|
+
}
|
522
|
+
),
|
523
|
+
)[
|
524
|
+
"data"
|
525
|
+
][
|
526
|
+
"main"
|
527
|
+
]
|
528
|
+
if len(local_list_authentication_user_response) != 1:
|
529
|
+
output_content = get_api_output_in_standard_format(
|
530
|
+
message=messages["INCORRECT_USERNAME"],
|
531
|
+
log=f"incorrect username {username}",
|
532
|
+
)
|
533
|
+
return JSONResponse(
|
534
|
+
status_code=status.HTTP_400_BAD_REQUEST, content=output_content
|
535
|
+
)
|
536
|
+
# validate if app_id is assigned to user
|
537
|
+
# this will also validate if app_id is valid
|
538
|
+
local_dict_user = local_list_authentication_user_response[0]
|
539
|
+
local_str_user_id = local_dict_user[UserCredential.user_id.name]
|
540
|
+
local_list_user_app_response = global_object_square_database_helper.get_rows_v0(
|
541
|
+
database_name=global_string_database_name,
|
542
|
+
schema_name=global_string_schema_name,
|
543
|
+
table_name=UserApp.__tablename__,
|
544
|
+
filters=FiltersV0(
|
545
|
+
{
|
546
|
+
UserApp.user_id.name: FilterConditionsV0(eq=local_str_user_id),
|
547
|
+
UserApp.app_id.name: FilterConditionsV0(eq=app_id),
|
548
|
+
}
|
549
|
+
),
|
550
|
+
)["data"]["main"]
|
551
|
+
if len(local_list_user_app_response) != 1:
|
552
|
+
output_content = get_api_output_in_standard_format(
|
553
|
+
message=messages["GENERIC_400"],
|
554
|
+
log=f"user_id {local_str_user_id}({username}) not assigned to app {app_id}.",
|
555
|
+
)
|
556
|
+
return JSONResponse(
|
557
|
+
status_code=status.HTTP_400_BAD_REQUEST, content=output_content
|
558
|
+
)
|
559
|
+
|
560
|
+
# validate password
|
561
|
+
if not (
|
562
|
+
bcrypt.checkpw(
|
563
|
+
password.encode("utf-8"),
|
564
|
+
local_dict_user[
|
565
|
+
UserCredential.user_credential_hashed_password.name
|
566
|
+
].encode("utf-8"),
|
567
|
+
)
|
568
|
+
):
|
569
|
+
output_content = get_api_output_in_standard_format(
|
570
|
+
message=messages["INCORRECT_PASSWORD"],
|
571
|
+
log=f"incorrect password for user_id {local_str_user_id}({username}).",
|
572
|
+
)
|
573
|
+
return JSONResponse(
|
574
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
575
|
+
content=output_content,
|
576
|
+
)
|
577
|
+
"""
|
578
|
+
main process
|
579
|
+
"""
|
580
|
+
# return new access token and refresh token
|
95
581
|
|
96
582
|
# create access token
|
97
583
|
local_dict_access_token_payload = {
|
584
|
+
"app_id": app_id,
|
98
585
|
"user_id": local_str_user_id,
|
99
586
|
"exp": datetime.now(timezone.utc)
|
100
|
-
|
587
|
+
+ timedelta(minutes=config_int_access_token_valid_minutes),
|
101
588
|
}
|
102
589
|
local_str_access_token = jwt.encode(
|
103
|
-
local_dict_access_token_payload,
|
590
|
+
local_dict_access_token_payload,
|
591
|
+
config_str_secret_key_for_access_token,
|
104
592
|
)
|
105
593
|
|
106
594
|
# create refresh token
|
@@ -109,222 +597,189 @@ async def register_username(username: str, password: str):
|
|
109
597
|
)
|
110
598
|
|
111
599
|
local_dict_refresh_token_payload = {
|
600
|
+
"app_id": app_id,
|
112
601
|
"user_id": local_str_user_id,
|
113
602
|
"exp": local_object_refresh_token_expiry_time,
|
114
603
|
}
|
115
604
|
local_str_refresh_token = jwt.encode(
|
116
|
-
local_dict_refresh_token_payload,
|
605
|
+
local_dict_refresh_token_payload,
|
606
|
+
config_str_secret_key_for_refresh_token,
|
117
607
|
)
|
118
|
-
try:
|
119
|
-
local_list_response_authentication_username = global_object_square_database_helper.insert_rows(
|
120
|
-
data=[
|
121
|
-
{
|
122
|
-
UserCredential.user_id.name: local_str_user_id,
|
123
|
-
UserCredential.user_credential_username.name: username,
|
124
|
-
UserCredential.user_credential_hashed_password.name: local_str_hashed_password,
|
125
|
-
}
|
126
|
-
],
|
127
|
-
database_name=local_string_database_name,
|
128
|
-
schema_name=local_string_schema_name,
|
129
|
-
table_name=UserCredential.__tablename__,
|
130
|
-
)
|
131
|
-
except HTTPError as http_error:
|
132
|
-
if http_error.response.status_code == 400:
|
133
|
-
return JSONResponse(
|
134
|
-
status_code=status.HTTP_409_CONFLICT,
|
135
|
-
content=f"an account with the username {username} already exists.",
|
136
|
-
)
|
137
|
-
else:
|
138
|
-
raise http_error
|
139
|
-
# ======================================================================================
|
140
|
-
|
141
|
-
# ======================================================================================
|
142
608
|
# entry in user session table
|
143
|
-
|
609
|
+
global_object_square_database_helper.insert_rows_v0(
|
144
610
|
data=[
|
145
611
|
{
|
146
612
|
UserSession.user_id.name: local_str_user_id,
|
613
|
+
UserSession.app_id.name: app_id,
|
147
614
|
UserSession.user_session_refresh_token.name: local_str_refresh_token,
|
148
615
|
UserSession.user_session_expiry_time.name: local_object_refresh_token_expiry_time.strftime(
|
149
616
|
"%Y-%m-%d %H:%M:%S.%f+00"
|
150
617
|
),
|
151
618
|
}
|
152
619
|
],
|
153
|
-
database_name=
|
154
|
-
schema_name=
|
620
|
+
database_name=global_string_database_name,
|
621
|
+
schema_name=global_string_schema_name,
|
155
622
|
table_name=UserSession.__tablename__,
|
156
623
|
)
|
157
|
-
|
624
|
+
"""
|
625
|
+
return value
|
626
|
+
"""
|
627
|
+
output_content = get_api_output_in_standard_format(
|
628
|
+
data={
|
629
|
+
"main": {
|
630
|
+
"user_id": local_str_user_id,
|
631
|
+
"access_token": local_str_access_token,
|
632
|
+
"refresh_token": local_str_refresh_token,
|
633
|
+
}
|
634
|
+
},
|
635
|
+
message=messages["LOGIN_SUCCESSFUL"],
|
636
|
+
)
|
158
637
|
return JSONResponse(
|
159
638
|
status_code=status.HTTP_200_OK,
|
160
|
-
content=
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
639
|
+
content=output_content,
|
640
|
+
)
|
641
|
+
except HTTPException as http_exception:
|
642
|
+
return JSONResponse(
|
643
|
+
status_code=http_exception.status_code, content=http_exception.detail
|
165
644
|
)
|
166
645
|
except Exception as e:
|
646
|
+
"""
|
647
|
+
rollback logic
|
648
|
+
"""
|
167
649
|
global_object_square_logger.logger.error(e, exc_info=True)
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
table_name=User.__tablename__,
|
173
|
-
filters={User.user_id.name: local_str_user_id},
|
174
|
-
)
|
650
|
+
output_content = get_api_output_in_standard_format(
|
651
|
+
message=messages["GENERIC_500"],
|
652
|
+
log=str(e),
|
653
|
+
)
|
175
654
|
return JSONResponse(
|
176
|
-
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=
|
655
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
177
656
|
)
|
178
657
|
|
179
658
|
|
180
|
-
@router.get("/
|
659
|
+
@router.get("/generate_access_token/v0")
|
181
660
|
@global_object_square_logger.async_auto_logger
|
182
|
-
async def
|
661
|
+
async def generate_access_token_v0(
|
662
|
+
refresh_token: Annotated[str, Header()],
|
663
|
+
):
|
183
664
|
try:
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
665
|
+
"""
|
666
|
+
validation
|
667
|
+
"""
|
668
|
+
# validate refresh token
|
669
|
+
# validating if a session refresh token exists in the database.
|
670
|
+
local_list_user_session_response = (
|
671
|
+
global_object_square_database_helper.get_rows_v0(
|
672
|
+
database_name=global_string_database_name,
|
673
|
+
schema_name=global_string_schema_name,
|
674
|
+
table_name=UserSession.__tablename__,
|
675
|
+
filters=FiltersV0(
|
676
|
+
{
|
677
|
+
UserSession.user_session_refresh_token.name: FilterConditionsV0(
|
678
|
+
eq=refresh_token
|
679
|
+
),
|
680
|
+
}
|
681
|
+
),
|
682
|
+
)["data"]["main"]
|
193
683
|
)
|
194
|
-
# ======================================================================================
|
195
684
|
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
685
|
+
if len(local_list_user_session_response) != 1:
|
686
|
+
output_content = get_api_output_in_standard_format(
|
687
|
+
message=messages["INCORRECT_REFRESH_TOKEN"],
|
688
|
+
log=f"incorrect refresh token: {refresh_token}.",
|
689
|
+
)
|
200
690
|
return JSONResponse(
|
201
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
691
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
692
|
+
content=output_content,
|
202
693
|
)
|
203
|
-
#
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
"user_id": local_str_user_id,
|
245
|
-
"exp": local_object_refresh_token_expiry_time,
|
246
|
-
}
|
247
|
-
local_str_refresh_token = jwt.encode(
|
248
|
-
local_dict_refresh_token_payload,
|
249
|
-
config_str_secret_key_for_refresh_token,
|
250
|
-
)
|
251
|
-
# ======================================================================================
|
252
|
-
# entry in user session table
|
253
|
-
local_list_response_user_session = global_object_square_database_helper.insert_rows(
|
254
|
-
data=[
|
255
|
-
{
|
256
|
-
UserSession.user_id.name: local_str_user_id,
|
257
|
-
UserSession.user_session_refresh_token.name: local_str_refresh_token,
|
258
|
-
UserSession.user_session_expiry_time.name: local_object_refresh_token_expiry_time.strftime(
|
259
|
-
"%Y-%m-%d %H:%M:%S.%f+00"
|
260
|
-
),
|
261
|
-
}
|
262
|
-
],
|
263
|
-
database_name=local_string_database_name,
|
264
|
-
schema_name=local_string_schema_name,
|
265
|
-
table_name=UserSession.__tablename__,
|
266
|
-
)
|
267
|
-
# ======================================================================================
|
268
|
-
return JSONResponse(
|
269
|
-
status_code=status.HTTP_200_OK,
|
270
|
-
content={
|
271
|
-
"user_id": local_str_user_id,
|
272
|
-
"access_token": local_str_access_token,
|
273
|
-
"refresh_token": local_str_refresh_token,
|
274
|
-
},
|
275
|
-
)
|
276
|
-
# ======================================================================================
|
277
|
-
|
694
|
+
# validating if the refresh token is valid, active and of the same user.
|
695
|
+
try:
|
696
|
+
local_dict_refresh_token_payload = get_jwt_payload(
|
697
|
+
refresh_token, config_str_secret_key_for_refresh_token
|
698
|
+
)
|
699
|
+
except Exception as error:
|
700
|
+
output_content = get_api_output_in_standard_format(
|
701
|
+
message=messages["INCORRECT_REFRESH_TOKEN"], log=str(error)
|
702
|
+
)
|
703
|
+
return JSONResponse(
|
704
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
705
|
+
content=output_content,
|
706
|
+
)
|
707
|
+
"""
|
708
|
+
main process
|
709
|
+
"""
|
710
|
+
# create and send access token
|
711
|
+
local_dict_access_token_payload = {
|
712
|
+
"app_id": local_dict_refresh_token_payload["app_id"],
|
713
|
+
"user_id": local_dict_refresh_token_payload["user_id"],
|
714
|
+
"exp": datetime.now(timezone.utc)
|
715
|
+
+ timedelta(minutes=config_int_access_token_valid_minutes),
|
716
|
+
}
|
717
|
+
local_str_access_token = jwt.encode(
|
718
|
+
local_dict_access_token_payload, config_str_secret_key_for_access_token
|
719
|
+
)
|
720
|
+
"""
|
721
|
+
return value
|
722
|
+
"""
|
723
|
+
output_content = get_api_output_in_standard_format(
|
724
|
+
data={"main": {"access_token": local_str_access_token}},
|
725
|
+
message=messages["GENERIC_CREATION_SUCCESSFUL"],
|
726
|
+
)
|
727
|
+
return JSONResponse(
|
728
|
+
status_code=status.HTTP_200_OK,
|
729
|
+
content=output_content,
|
730
|
+
)
|
731
|
+
except HTTPException as http_exception:
|
732
|
+
return JSONResponse(
|
733
|
+
status_code=http_exception.status_code, content=http_exception.detail
|
734
|
+
)
|
278
735
|
except Exception as e:
|
736
|
+
"""
|
737
|
+
rollback logic
|
738
|
+
"""
|
279
739
|
global_object_square_logger.logger.error(e, exc_info=True)
|
740
|
+
output_content = get_api_output_in_standard_format(
|
741
|
+
message=messages["GENERIC_500"],
|
742
|
+
log=str(e),
|
743
|
+
)
|
280
744
|
return JSONResponse(
|
281
|
-
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=
|
745
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
282
746
|
)
|
283
747
|
|
284
748
|
|
285
|
-
@router.
|
749
|
+
@router.delete("/logout/v0")
|
286
750
|
@global_object_square_logger.async_auto_logger
|
287
|
-
async def
|
288
|
-
|
751
|
+
async def logout_v0(
|
752
|
+
refresh_token: Annotated[str, Header()],
|
289
753
|
):
|
290
754
|
try:
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
database_name=local_string_database_name,
|
295
|
-
schema_name=local_string_schema_name,
|
296
|
-
table_name=User.__tablename__,
|
297
|
-
filters={User.user_id.name: user_id},
|
298
|
-
)
|
299
|
-
|
300
|
-
if len(local_list_user_response) != 1:
|
301
|
-
return JSONResponse(
|
302
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
303
|
-
content=f"incorrect user_id: {user_id}.",
|
304
|
-
)
|
305
|
-
# ======================================================================================
|
306
|
-
|
307
|
-
# ======================================================================================
|
755
|
+
"""
|
756
|
+
validation
|
757
|
+
"""
|
308
758
|
# validate refresh token
|
309
|
-
|
310
759
|
# validating if a session refresh token exists in the database.
|
311
760
|
local_list_user_session_response = (
|
312
|
-
global_object_square_database_helper.
|
313
|
-
database_name=
|
314
|
-
schema_name=
|
761
|
+
global_object_square_database_helper.get_rows_v0(
|
762
|
+
database_name=global_string_database_name,
|
763
|
+
schema_name=global_string_schema_name,
|
315
764
|
table_name=UserSession.__tablename__,
|
316
|
-
filters=
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
765
|
+
filters=FiltersV0(
|
766
|
+
{
|
767
|
+
UserSession.user_session_refresh_token.name: FilterConditionsV0(
|
768
|
+
eq=refresh_token
|
769
|
+
),
|
770
|
+
}
|
771
|
+
),
|
772
|
+
)["data"]["main"]
|
321
773
|
)
|
322
774
|
|
323
775
|
if len(local_list_user_session_response) != 1:
|
776
|
+
output_content = get_api_output_in_standard_format(
|
777
|
+
message=messages["INCORRECT_REFRESH_TOKEN"],
|
778
|
+
log=f"incorrect refresh token: {refresh_token}.",
|
779
|
+
)
|
324
780
|
return JSONResponse(
|
325
781
|
status_code=status.HTTP_400_BAD_REQUEST,
|
326
|
-
content=
|
327
|
-
f"for user_id: {user_id}.",
|
782
|
+
content=output_content,
|
328
783
|
)
|
329
784
|
# validating if the refresh token is valid, active and of the same user.
|
330
785
|
try:
|
@@ -332,133 +787,384 @@ async def generate_access_token(
|
|
332
787
|
refresh_token, config_str_secret_key_for_refresh_token
|
333
788
|
)
|
334
789
|
except Exception as error:
|
335
|
-
|
336
|
-
|
337
|
-
|
790
|
+
output_content = get_api_output_in_standard_format(
|
791
|
+
message=messages["INCORRECT_REFRESH_TOKEN"],
|
792
|
+
log=str(error),
|
338
793
|
)
|
339
|
-
|
340
|
-
if local_dict_refresh_token_payload["user_id"] != user_id:
|
341
794
|
return JSONResponse(
|
342
795
|
status_code=status.HTTP_400_BAD_REQUEST,
|
343
|
-
content=
|
796
|
+
content=output_content,
|
344
797
|
)
|
345
|
-
|
346
798
|
# ======================================================================================
|
799
|
+
# NOTE: if refresh token has expired no need to delete it during this call
|
347
800
|
# ======================================================================================
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
801
|
+
"""
|
802
|
+
main process
|
803
|
+
"""
|
804
|
+
# delete session for user
|
805
|
+
global_object_square_database_helper.delete_rows_v0(
|
806
|
+
database_name=global_string_database_name,
|
807
|
+
schema_name=global_string_schema_name,
|
808
|
+
table_name=UserSession.__tablename__,
|
809
|
+
filters=FiltersV0(
|
810
|
+
{
|
811
|
+
UserSession.user_session_refresh_token.name: FilterConditionsV0(
|
812
|
+
eq=refresh_token
|
813
|
+
),
|
814
|
+
}
|
815
|
+
),
|
356
816
|
)
|
357
|
-
|
817
|
+
"""
|
818
|
+
return value
|
819
|
+
"""
|
820
|
+
output_content = get_api_output_in_standard_format(
|
821
|
+
message=messages["LOGOUT_SUCCESSFUL"],
|
822
|
+
)
|
823
|
+
return JSONResponse(status_code=status.HTTP_200_OK, content=output_content)
|
824
|
+
except HTTPException as http_exception:
|
358
825
|
return JSONResponse(
|
359
|
-
status_code=
|
360
|
-
content={"access_token": local_str_access_token},
|
826
|
+
status_code=http_exception.status_code, content=http_exception.detail
|
361
827
|
)
|
362
|
-
# ======================================================================================
|
363
|
-
|
364
828
|
except Exception as e:
|
829
|
+
"""
|
830
|
+
rollback logic
|
831
|
+
"""
|
365
832
|
global_object_square_logger.logger.error(e, exc_info=True)
|
833
|
+
output_content = get_api_output_in_standard_format(
|
834
|
+
message=messages["GENERIC_500"],
|
835
|
+
log=str(e),
|
836
|
+
)
|
366
837
|
return JSONResponse(
|
367
|
-
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=
|
838
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
368
839
|
)
|
369
840
|
|
370
841
|
|
371
|
-
@router.
|
842
|
+
@router.patch("/update_username/v0")
|
372
843
|
@global_object_square_logger.async_auto_logger
|
373
|
-
async def
|
374
|
-
|
375
|
-
|
376
|
-
refresh_token: Annotated[Union[str, None], Header()],
|
844
|
+
async def update_username_v0(
|
845
|
+
new_username: str,
|
846
|
+
access_token: Annotated[str, Header()],
|
377
847
|
):
|
378
848
|
try:
|
379
|
-
|
849
|
+
"""
|
850
|
+
validation
|
851
|
+
"""
|
852
|
+
# validate access token
|
853
|
+
try:
|
854
|
+
local_dict_access_token_payload = get_jwt_payload(
|
855
|
+
access_token, config_str_secret_key_for_access_token
|
856
|
+
)
|
857
|
+
except Exception as error:
|
858
|
+
output_content = get_api_output_in_standard_format(
|
859
|
+
message=messages["INCORRECT_ACCESS_TOKEN"], log=str(error)
|
860
|
+
)
|
861
|
+
return JSONResponse(
|
862
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
863
|
+
content=output_content,
|
864
|
+
)
|
865
|
+
user_id = local_dict_access_token_payload["user_id"]
|
866
|
+
|
380
867
|
# validate user_id
|
381
|
-
local_list_user_response = global_object_square_database_helper.
|
382
|
-
database_name=
|
383
|
-
schema_name=
|
868
|
+
local_list_user_response = global_object_square_database_helper.get_rows_v0(
|
869
|
+
database_name=global_string_database_name,
|
870
|
+
schema_name=global_string_schema_name,
|
384
871
|
table_name=User.__tablename__,
|
385
|
-
filters=
|
386
|
-
|
872
|
+
filters=FiltersV0(
|
873
|
+
{
|
874
|
+
User.user_id.name: FilterConditionsV0(eq=user_id),
|
875
|
+
}
|
876
|
+
),
|
877
|
+
)["data"]["main"]
|
387
878
|
|
388
879
|
if len(local_list_user_response) != 1:
|
880
|
+
output_content = get_api_output_in_standard_format(
|
881
|
+
message=messages["INCORRECT_USER_ID"],
|
882
|
+
log=f"incorrect user_id: {user_id}.",
|
883
|
+
)
|
389
884
|
return JSONResponse(
|
390
885
|
status_code=status.HTTP_400_BAD_REQUEST,
|
391
|
-
content=
|
886
|
+
content=output_content,
|
392
887
|
)
|
393
|
-
# ======================================================================================
|
394
888
|
|
395
|
-
#
|
396
|
-
|
889
|
+
# validate new username
|
890
|
+
local_list_user_credentials_response = global_object_square_database_helper.get_rows_v0(
|
891
|
+
database_name=global_string_database_name,
|
892
|
+
schema_name=global_string_schema_name,
|
893
|
+
table_name=UserCredential.__tablename__,
|
894
|
+
filters=FiltersV0(
|
895
|
+
{
|
896
|
+
UserCredential.user_credential_username.name: FilterConditionsV0(
|
897
|
+
eq=new_username
|
898
|
+
),
|
899
|
+
}
|
900
|
+
),
|
901
|
+
)[
|
902
|
+
"data"
|
903
|
+
][
|
904
|
+
"main"
|
905
|
+
]
|
906
|
+
if len(local_list_user_credentials_response) != 0:
|
907
|
+
output_content = get_api_output_in_standard_format(
|
908
|
+
message=messages["USERNAME_ALREADY_EXISTS"],
|
909
|
+
log=f"{new_username} is taken.",
|
910
|
+
)
|
911
|
+
return JSONResponse(
|
912
|
+
status_code=status.HTTP_409_CONFLICT,
|
913
|
+
content=output_content,
|
914
|
+
)
|
915
|
+
"""
|
916
|
+
main process
|
917
|
+
"""
|
918
|
+
# edit the username
|
919
|
+
global_object_square_database_helper.edit_rows_v0(
|
920
|
+
database_name=global_string_database_name,
|
921
|
+
schema_name=global_string_schema_name,
|
922
|
+
table_name=UserCredential.__tablename__,
|
923
|
+
filters=FiltersV0(
|
924
|
+
{
|
925
|
+
UserCredential.user_id.name: FilterConditionsV0(eq=user_id),
|
926
|
+
}
|
927
|
+
),
|
928
|
+
data={
|
929
|
+
UserCredential.user_credential_username.name: new_username,
|
930
|
+
},
|
931
|
+
)
|
932
|
+
"""
|
933
|
+
return value
|
934
|
+
"""
|
935
|
+
output_content = get_api_output_in_standard_format(
|
936
|
+
data={"main": {"user_id": user_id, "username": new_username}},
|
937
|
+
message=messages["GENERIC_UPDATE_SUCCESSFUL"],
|
938
|
+
)
|
939
|
+
return JSONResponse(status_code=status.HTTP_200_OK, content=output_content)
|
940
|
+
except HTTPException as http_exception:
|
941
|
+
return JSONResponse(
|
942
|
+
status_code=http_exception.status_code, content=http_exception.detail
|
943
|
+
)
|
944
|
+
except Exception as e:
|
945
|
+
"""
|
946
|
+
rollback logic
|
947
|
+
"""
|
948
|
+
global_object_square_logger.logger.error(e, exc_info=True)
|
949
|
+
output_content = get_api_output_in_standard_format(
|
950
|
+
message=messages["GENERIC_500"],
|
951
|
+
log=str(e),
|
952
|
+
)
|
953
|
+
return JSONResponse(
|
954
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
955
|
+
)
|
397
956
|
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
957
|
+
|
958
|
+
@router.delete("/delete_user/v0")
|
959
|
+
@global_object_square_logger.async_auto_logger
|
960
|
+
async def delete_user_v0(
|
961
|
+
body: DeleteUserV0,
|
962
|
+
access_token: Annotated[str, Header()],
|
963
|
+
):
|
964
|
+
password = body.password
|
965
|
+
try:
|
966
|
+
"""
|
967
|
+
validation
|
968
|
+
"""
|
969
|
+
# validate access token
|
970
|
+
try:
|
971
|
+
local_dict_access_token_payload = get_jwt_payload(
|
972
|
+
access_token, config_str_secret_key_for_access_token
|
408
973
|
)
|
974
|
+
except Exception as error:
|
975
|
+
output_content = get_api_output_in_standard_format(
|
976
|
+
message=messages["INCORRECT_ACCESS_TOKEN"], log=str(error)
|
977
|
+
)
|
978
|
+
return JSONResponse(
|
979
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
980
|
+
content=output_content,
|
981
|
+
)
|
982
|
+
user_id = local_dict_access_token_payload["user_id"]
|
983
|
+
|
984
|
+
# validate user_id
|
985
|
+
local_list_authentication_user_response = (
|
986
|
+
global_object_square_database_helper.get_rows_v0(
|
987
|
+
database_name=global_string_database_name,
|
988
|
+
schema_name=global_string_schema_name,
|
989
|
+
table_name=UserCredential.__tablename__,
|
990
|
+
filters=FiltersV0(
|
991
|
+
{UserCredential.user_id.name: FilterConditionsV0(eq=user_id)}
|
992
|
+
),
|
993
|
+
)["data"]["main"]
|
409
994
|
)
|
995
|
+
if len(local_list_authentication_user_response) != 1:
|
996
|
+
output_content = get_api_output_in_standard_format(
|
997
|
+
message=messages["INCORRECT_USER_ID"],
|
998
|
+
log=f"incorrect user_id: {user_id}.",
|
999
|
+
)
|
1000
|
+
return JSONResponse(
|
1001
|
+
status_code=status.HTTP_400_BAD_REQUEST, content=output_content
|
1002
|
+
)
|
410
1003
|
|
411
|
-
|
1004
|
+
# validate password
|
1005
|
+
local_dict_user = local_list_authentication_user_response[0]
|
1006
|
+
if not (
|
1007
|
+
bcrypt.checkpw(
|
1008
|
+
password.encode("utf-8"),
|
1009
|
+
local_dict_user[
|
1010
|
+
UserCredential.user_credential_hashed_password.name
|
1011
|
+
].encode("utf-8"),
|
1012
|
+
)
|
1013
|
+
):
|
1014
|
+
output_content = get_api_output_in_standard_format(
|
1015
|
+
message=messages["INCORRECT_PASSWORD"],
|
1016
|
+
log=f"incorrect password for user_id {user_id}.",
|
1017
|
+
)
|
412
1018
|
return JSONResponse(
|
413
1019
|
status_code=status.HTTP_400_BAD_REQUEST,
|
414
|
-
content=
|
415
|
-
f"for user_id: {user_id}.",
|
1020
|
+
content=output_content,
|
416
1021
|
)
|
417
|
-
|
418
|
-
|
1022
|
+
"""
|
1023
|
+
main process
|
1024
|
+
"""
|
1025
|
+
# delete the user.
|
1026
|
+
global_object_square_database_helper.delete_rows_v0(
|
1027
|
+
database_name=global_string_database_name,
|
1028
|
+
schema_name=global_string_schema_name,
|
1029
|
+
table_name=User.__tablename__,
|
1030
|
+
filters=FiltersV0(
|
1031
|
+
{
|
1032
|
+
User.user_id.name: FilterConditionsV0(eq=user_id),
|
1033
|
+
}
|
1034
|
+
),
|
1035
|
+
)
|
1036
|
+
"""
|
1037
|
+
return value
|
1038
|
+
"""
|
1039
|
+
output_content = get_api_output_in_standard_format(
|
1040
|
+
message=messages["GENERIC_DELETE_SUCCESSFUL"],
|
1041
|
+
log=f"user_id: {user_id} deleted successfully.",
|
1042
|
+
)
|
1043
|
+
return JSONResponse(status_code=status.HTTP_200_OK, content=output_content)
|
1044
|
+
except HTTPException as http_exception:
|
1045
|
+
return JSONResponse(
|
1046
|
+
status_code=http_exception.status_code, content=http_exception.detail
|
1047
|
+
)
|
1048
|
+
except Exception as e:
|
1049
|
+
"""
|
1050
|
+
rollback logic
|
1051
|
+
"""
|
1052
|
+
global_object_square_logger.logger.error(e, exc_info=True)
|
1053
|
+
output_content = get_api_output_in_standard_format(
|
1054
|
+
message=messages["GENERIC_500"],
|
1055
|
+
log=str(e),
|
1056
|
+
)
|
1057
|
+
return JSONResponse(
|
1058
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
1059
|
+
)
|
419
1060
|
|
420
|
-
|
1061
|
+
|
1062
|
+
@router.patch("/update_password/v0")
|
1063
|
+
@global_object_square_logger.async_auto_logger
|
1064
|
+
async def update_password_v0(
|
1065
|
+
body: UpdatePasswordV0,
|
1066
|
+
access_token: Annotated[str, Header()],
|
1067
|
+
):
|
1068
|
+
old_password = body.old_password
|
1069
|
+
new_password = body.new_password
|
1070
|
+
try:
|
1071
|
+
"""
|
1072
|
+
validation
|
1073
|
+
"""
|
421
1074
|
# validate access token
|
422
|
-
# validating if the access token is valid, active and of the same user.
|
423
1075
|
try:
|
424
1076
|
local_dict_access_token_payload = get_jwt_payload(
|
425
1077
|
access_token, config_str_secret_key_for_access_token
|
426
1078
|
)
|
427
1079
|
except Exception as error:
|
428
|
-
|
429
|
-
|
430
|
-
content=str(error),
|
1080
|
+
output_content = get_api_output_in_standard_format(
|
1081
|
+
message=messages["INCORRECT_ACCESS_TOKEN"], log=str(error)
|
431
1082
|
)
|
432
|
-
if local_dict_access_token_payload["user_id"] != user_id:
|
433
1083
|
return JSONResponse(
|
434
1084
|
status_code=status.HTTP_400_BAD_REQUEST,
|
435
|
-
content=
|
1085
|
+
content=output_content,
|
436
1086
|
)
|
1087
|
+
user_id = local_dict_access_token_payload["user_id"]
|
437
1088
|
|
438
|
-
#
|
439
|
-
|
440
|
-
|
441
|
-
|
1089
|
+
# validate user_id
|
1090
|
+
local_list_authentication_user_response = (
|
1091
|
+
global_object_square_database_helper.get_rows_v0(
|
1092
|
+
database_name=global_string_database_name,
|
1093
|
+
schema_name=global_string_schema_name,
|
1094
|
+
table_name=UserCredential.__tablename__,
|
1095
|
+
filters=FiltersV0(
|
1096
|
+
{UserCredential.user_id.name: FilterConditionsV0(eq=user_id)}
|
1097
|
+
),
|
1098
|
+
)["data"]["main"]
|
1099
|
+
)
|
1100
|
+
if len(local_list_authentication_user_response) != 1:
|
1101
|
+
output_content = get_api_output_in_standard_format(
|
1102
|
+
message=messages["INCORRECT_USER_ID"],
|
1103
|
+
log=f"incorrect user_id: {user_id}.",
|
1104
|
+
)
|
1105
|
+
return JSONResponse(
|
1106
|
+
status_code=status.HTTP_400_BAD_REQUEST, content=output_content
|
1107
|
+
)
|
442
1108
|
|
443
|
-
#
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
1109
|
+
# validate password
|
1110
|
+
local_dict_user = local_list_authentication_user_response[0]
|
1111
|
+
if not (
|
1112
|
+
bcrypt.checkpw(
|
1113
|
+
old_password.encode("utf-8"),
|
1114
|
+
local_dict_user[
|
1115
|
+
UserCredential.user_credential_hashed_password.name
|
1116
|
+
].encode("utf-8"),
|
1117
|
+
)
|
1118
|
+
):
|
1119
|
+
output_content = get_api_output_in_standard_format(
|
1120
|
+
message=messages["INCORRECT_PASSWORD"],
|
1121
|
+
log=f"incorrect password for user_id {user_id}.",
|
1122
|
+
)
|
1123
|
+
return JSONResponse(
|
1124
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
1125
|
+
content=output_content,
|
1126
|
+
)
|
1127
|
+
"""
|
1128
|
+
main process
|
1129
|
+
"""
|
1130
|
+
# delete the user.
|
1131
|
+
local_str_hashed_password = bcrypt.hashpw(
|
1132
|
+
new_password.encode("utf-8"), bcrypt.gensalt()
|
1133
|
+
).decode("utf-8")
|
1134
|
+
global_object_square_database_helper.edit_rows_v0(
|
1135
|
+
database_name=global_string_database_name,
|
1136
|
+
schema_name=global_string_schema_name,
|
1137
|
+
table_name=UserCredential.__tablename__,
|
1138
|
+
filters=FiltersV0(
|
1139
|
+
{
|
1140
|
+
UserCredential.user_id.name: FilterConditionsV0(eq=user_id),
|
1141
|
+
}
|
1142
|
+
),
|
1143
|
+
data={
|
1144
|
+
UserCredential.user_credential_hashed_password.name: local_str_hashed_password,
|
452
1145
|
},
|
453
1146
|
)
|
454
|
-
|
1147
|
+
"""
|
1148
|
+
return value
|
1149
|
+
"""
|
1150
|
+
output_content = get_api_output_in_standard_format(
|
1151
|
+
message=messages["GENERIC_UPDATE_SUCCESSFUL"],
|
1152
|
+
log=f"password for user_id: {user_id} updated successfully.",
|
1153
|
+
)
|
1154
|
+
return JSONResponse(status_code=status.HTTP_200_OK, content=output_content)
|
1155
|
+
except HTTPException as http_exception:
|
455
1156
|
return JSONResponse(
|
456
|
-
status_code=
|
1157
|
+
status_code=http_exception.status_code, content=http_exception.detail
|
457
1158
|
)
|
458
|
-
# ======================================================================================
|
459
|
-
|
460
1159
|
except Exception as e:
|
1160
|
+
"""
|
1161
|
+
rollback logic
|
1162
|
+
"""
|
461
1163
|
global_object_square_logger.logger.error(e, exc_info=True)
|
1164
|
+
output_content = get_api_output_in_standard_format(
|
1165
|
+
message=messages["GENERIC_500"],
|
1166
|
+
log=str(e),
|
1167
|
+
)
|
462
1168
|
return JSONResponse(
|
463
|
-
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=
|
1169
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
464
1170
|
)
|