square-authentication 1.0.0__py3-none-any.whl → 2.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 +16 -0
- square_authentication/routes/core.py +674 -267
- square_authentication/routes/utility.py +3 -1
- {square_authentication-1.0.0.dist-info → square_authentication-2.0.0.dist-info}/METADATA +19 -4
- square_authentication-2.0.0.dist-info/RECORD +15 -0
- square_authentication-1.0.0.dist-info/RECORD +0 -14
- {square_authentication-1.0.0.dist-info → square_authentication-2.0.0.dist-info}/WHEEL +0 -0
- {square_authentication-1.0.0.dist-info → square_authentication-2.0.0.dist-info}/top_level.txt +0 -0
@@ -6,11 +6,11 @@ from square_logger.main import SquareLogger
|
|
6
6
|
|
7
7
|
try:
|
8
8
|
config_file_path = (
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
os.path.dirname(os.path.abspath(__file__))
|
10
|
+
+ os.sep
|
11
|
+
+ "data"
|
12
|
+
+ os.sep
|
13
|
+
+ "config.ini"
|
14
14
|
)
|
15
15
|
ldict_configuration = ConfigReader(config_file_path).read_configuration()
|
16
16
|
|
square_authentication/main.py
CHANGED
@@ -3,6 +3,7 @@ import os.path
|
|
3
3
|
from fastapi import FastAPI, status
|
4
4
|
from fastapi.middleware.cors import CORSMiddleware
|
5
5
|
from fastapi.responses import JSONResponse
|
6
|
+
from square_commons import get_api_output_in_standard_format
|
6
7
|
from uvicorn import run
|
7
8
|
|
8
9
|
from square_authentication.configuration import (
|
@@ -31,15 +32,14 @@ app.include_router(utility.router)
|
|
31
32
|
@app.get("/")
|
32
33
|
@global_object_square_logger.async_auto_logger
|
33
34
|
async def root():
|
34
|
-
|
35
|
-
|
36
|
-
)
|
35
|
+
output_content = get_api_output_in_standard_format(log=config_str_module_name)
|
36
|
+
return JSONResponse(status_code=status.HTTP_200_OK, content=output_content)
|
37
37
|
|
38
38
|
|
39
39
|
if __name__ == "__main__":
|
40
40
|
try:
|
41
41
|
if os.path.exists(config_str_ssl_key_file_path) and os.path.exists(
|
42
|
-
|
42
|
+
config_str_ssl_crt_file_path
|
43
43
|
):
|
44
44
|
run(
|
45
45
|
app,
|
@@ -0,0 +1,16 @@
|
|
1
|
+
messages = {
|
2
|
+
"REGISTRATION_SUCCESSFUL": "registration was successful. welcome aboard!",
|
3
|
+
"LOGIN_SUCCESSFUL": "you have logged in successfully.",
|
4
|
+
"LOGOUT_SUCCESSFUL": "you have logged out successfully.",
|
5
|
+
"INCORRECT_USERNAME": "the username you entered does not exist.",
|
6
|
+
"INCORRECT_PASSWORD": "the password you entered is incorrect. please try again.",
|
7
|
+
"INCORRECT_USER_ID": "the user ID you provided does not exist or is invalid.",
|
8
|
+
"USERNAME_ALREADY_EXISTS": "the username you entered is already taken. please choose a different one.",
|
9
|
+
"INCORRECT_ACCESS_TOKEN": "the access token provided is invalid or expired.",
|
10
|
+
"INCORRECT_REFRESH_TOKEN": "the refresh token provided is invalid or expired.",
|
11
|
+
"GENERIC_READ_SUCCESSFUL": "data retrieved successfully.",
|
12
|
+
"GENERIC_CREATION_SUCCESSFUL": "records created successfully.",
|
13
|
+
"GENERIC_UPDATE_SUCCESSFUL": "your information has been updated successfully.",
|
14
|
+
"GENERIC_400": "the request is invalid or cannot be processed.",
|
15
|
+
"GENERIC_500": "an internal server error occurred. please try again later.",
|
16
|
+
}
|
@@ -1,22 +1,29 @@
|
|
1
1
|
from datetime import datetime, timedelta, timezone
|
2
|
-
from typing import Annotated,
|
2
|
+
from typing import Annotated, List
|
3
|
+
from uuid import UUID
|
3
4
|
|
4
5
|
import bcrypt
|
5
6
|
import jwt
|
6
|
-
from fastapi import APIRouter, status, Header
|
7
|
+
from fastapi import APIRouter, status, Header, HTTPException
|
7
8
|
from fastapi.responses import JSONResponse
|
8
|
-
from
|
9
|
+
from square_commons import get_api_output_in_standard_format
|
10
|
+
from square_database.pydantic_models.pydantic_models import (
|
11
|
+
FiltersV0,
|
12
|
+
FilterConditionsV0,
|
13
|
+
)
|
9
14
|
from square_database_helper.main import SquareDatabaseHelper
|
10
|
-
from square_database_structure.square
|
15
|
+
from square_database_structure.square import global_string_database_name
|
16
|
+
from square_database_structure.square.authentication import global_string_schema_name
|
11
17
|
from square_database_structure.square.authentication.tables import (
|
12
|
-
local_string_database_name,
|
13
|
-
local_string_schema_name,
|
14
18
|
User,
|
15
|
-
UserLog,
|
16
19
|
UserCredential,
|
17
|
-
UserProfile,
|
18
20
|
UserSession,
|
21
|
+
UserApp,
|
22
|
+
)
|
23
|
+
from square_database_structure.square.public import (
|
24
|
+
global_string_schema_name as global_string_public_schema_name,
|
19
25
|
)
|
26
|
+
from square_database_structure.square.public.tables import App
|
20
27
|
|
21
28
|
from square_authentication.configuration import (
|
22
29
|
global_object_square_logger,
|
@@ -28,6 +35,7 @@ from square_authentication.configuration import (
|
|
28
35
|
config_int_square_database_port,
|
29
36
|
config_str_square_database_protocol,
|
30
37
|
)
|
38
|
+
from square_authentication.messages import messages
|
31
39
|
from square_authentication.utils.token import get_jwt_payload
|
32
40
|
|
33
41
|
router = APIRouter(
|
@@ -41,66 +49,441 @@ global_object_square_database_helper = SquareDatabaseHelper(
|
|
41
49
|
)
|
42
50
|
|
43
51
|
|
44
|
-
@router.
|
52
|
+
@router.post("/register_username/v0")
|
45
53
|
@global_object_square_logger.async_auto_logger
|
46
|
-
async def
|
54
|
+
async def register_username_v0(username: str, password: str):
|
47
55
|
local_str_user_id = None
|
56
|
+
username = username.lower()
|
48
57
|
try:
|
49
|
-
|
58
|
+
"""
|
59
|
+
validation
|
60
|
+
"""
|
61
|
+
|
62
|
+
# validation for username
|
63
|
+
local_list_response_user_creds = global_object_square_database_helper.get_rows_v0(
|
64
|
+
database_name=global_string_database_name,
|
65
|
+
schema_name=global_string_schema_name,
|
66
|
+
table_name=UserCredential.__tablename__,
|
67
|
+
filters=FiltersV0(
|
68
|
+
{
|
69
|
+
UserCredential.user_credential_username.name: FilterConditionsV0(
|
70
|
+
eq=username
|
71
|
+
)
|
72
|
+
}
|
73
|
+
),
|
74
|
+
)[
|
75
|
+
"data"
|
76
|
+
][
|
77
|
+
"main"
|
78
|
+
]
|
79
|
+
if len(local_list_response_user_creds) > 0:
|
80
|
+
output_content = get_api_output_in_standard_format(
|
81
|
+
message=messages["USERNAME_ALREADY_EXISTS"],
|
82
|
+
log=f"an account with the username {username} already exists.",
|
83
|
+
)
|
84
|
+
raise HTTPException(
|
85
|
+
status_code=status.HTTP_409_CONFLICT,
|
86
|
+
detail=output_content,
|
87
|
+
)
|
88
|
+
|
89
|
+
"""
|
90
|
+
main process
|
91
|
+
"""
|
50
92
|
# entry in user table
|
51
|
-
local_list_response_user = global_object_square_database_helper.
|
93
|
+
local_list_response_user = global_object_square_database_helper.insert_rows_v0(
|
52
94
|
data=[{}],
|
53
|
-
database_name=
|
54
|
-
schema_name=
|
95
|
+
database_name=global_string_database_name,
|
96
|
+
schema_name=global_string_schema_name,
|
55
97
|
table_name=User.__tablename__,
|
56
|
-
)
|
98
|
+
)["data"]["main"]
|
57
99
|
local_str_user_id = local_list_response_user[0][User.user_id.name]
|
58
|
-
# ======================================================================================
|
59
100
|
|
60
|
-
#
|
61
|
-
|
62
|
-
|
101
|
+
# entry in credential table
|
102
|
+
|
103
|
+
# hash password
|
104
|
+
local_str_hashed_password = bcrypt.hashpw(
|
105
|
+
password.encode("utf-8"), bcrypt.gensalt()
|
106
|
+
).decode("utf-8")
|
107
|
+
|
108
|
+
global_object_square_database_helper.insert_rows_v0(
|
63
109
|
data=[
|
64
110
|
{
|
65
|
-
|
66
|
-
|
111
|
+
UserCredential.user_id.name: local_str_user_id,
|
112
|
+
UserCredential.user_credential_username.name: username,
|
113
|
+
UserCredential.user_credential_hashed_password.name: local_str_hashed_password,
|
67
114
|
}
|
68
115
|
],
|
69
|
-
database_name=
|
70
|
-
schema_name=
|
71
|
-
table_name=
|
116
|
+
database_name=global_string_database_name,
|
117
|
+
schema_name=global_string_schema_name,
|
118
|
+
table_name=UserCredential.__tablename__,
|
72
119
|
)
|
73
|
-
# ======================================================================================
|
74
120
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
121
|
+
"""
|
122
|
+
return value
|
123
|
+
"""
|
124
|
+
output_content = get_api_output_in_standard_format(
|
125
|
+
message=messages["REGISTRATION_SUCCESSFUL"],
|
126
|
+
data={"main": {"user_id": local_str_user_id, "username": username}},
|
127
|
+
)
|
128
|
+
return JSONResponse(
|
129
|
+
status_code=status.HTTP_201_CREATED,
|
130
|
+
content=output_content,
|
131
|
+
)
|
132
|
+
except HTTPException as http_exception:
|
133
|
+
return JSONResponse(
|
134
|
+
status_code=http_exception.status_code, content=http_exception.detail
|
135
|
+
)
|
136
|
+
except Exception as e:
|
137
|
+
global_object_square_logger.logger.error(e, exc_info=True)
|
138
|
+
"""
|
139
|
+
rollback logic
|
140
|
+
"""
|
141
|
+
if local_str_user_id:
|
142
|
+
global_object_square_database_helper.delete_rows_v0(
|
143
|
+
database_name=global_string_database_name,
|
144
|
+
schema_name=global_string_schema_name,
|
145
|
+
table_name=User.__tablename__,
|
146
|
+
filters=FiltersV0(
|
147
|
+
{User.user_id.name: FilterConditionsV0(eq=local_str_user_id)}
|
148
|
+
),
|
83
149
|
)
|
150
|
+
output_content = get_api_output_in_standard_format(
|
151
|
+
message=messages["GENERIC_500"],
|
152
|
+
log=str(e),
|
153
|
+
)
|
154
|
+
return JSONResponse(
|
155
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
84
156
|
)
|
85
157
|
|
86
|
-
# ======================================================================================
|
87
158
|
|
88
|
-
|
89
|
-
|
159
|
+
@router.get("/get_user_app_ids/v0")
|
160
|
+
@global_object_square_logger.async_auto_logger
|
161
|
+
async def get_user_app_ids_v0(user_id: UUID):
|
162
|
+
try:
|
163
|
+
local_string_user_id = str(user_id)
|
164
|
+
"""
|
165
|
+
validation
|
166
|
+
"""
|
167
|
+
|
168
|
+
local_list_response_user = global_object_square_database_helper.get_rows_v0(
|
169
|
+
database_name=global_string_database_name,
|
170
|
+
schema_name=global_string_schema_name,
|
171
|
+
table_name=User.__tablename__,
|
172
|
+
filters=FiltersV0(
|
173
|
+
{User.user_id.name: FilterConditionsV0(eq=local_string_user_id)}
|
174
|
+
),
|
175
|
+
)["data"]["main"]
|
176
|
+
if len(local_list_response_user) != 1:
|
177
|
+
output_content = get_api_output_in_standard_format(
|
178
|
+
message=messages["INCORRECT_USER_ID"],
|
179
|
+
log=f"invalid user_id: {local_string_user_id}",
|
180
|
+
)
|
181
|
+
raise HTTPException(
|
182
|
+
status_code=status.HTTP_404_NOT_FOUND,
|
183
|
+
detail=output_content,
|
184
|
+
)
|
185
|
+
"""
|
186
|
+
main process
|
187
|
+
"""
|
188
|
+
local_list_response_user_app = global_object_square_database_helper.get_rows_v0(
|
189
|
+
database_name=global_string_database_name,
|
190
|
+
schema_name=global_string_schema_name,
|
191
|
+
table_name=UserApp.__tablename__,
|
192
|
+
filters=FiltersV0(
|
193
|
+
{UserApp.user_id.name: FilterConditionsV0(eq=local_string_user_id)}
|
194
|
+
),
|
195
|
+
)["data"]["main"]
|
196
|
+
"""
|
197
|
+
return value
|
198
|
+
"""
|
199
|
+
output_content = get_api_output_in_standard_format(
|
200
|
+
message=messages["GENERIC_READ_SUCCESSFUL"],
|
201
|
+
data={
|
202
|
+
"main": [x[UserApp.app_id.name] for x in local_list_response_user_app]
|
203
|
+
},
|
204
|
+
)
|
205
|
+
return JSONResponse(
|
206
|
+
status_code=status.HTTP_200_OK,
|
207
|
+
content=output_content,
|
208
|
+
)
|
209
|
+
except HTTPException as http_exception:
|
210
|
+
return JSONResponse(
|
211
|
+
status_code=http_exception.status_code, content=http_exception.detail
|
212
|
+
)
|
213
|
+
except Exception as e:
|
214
|
+
"""
|
215
|
+
rollback logic
|
216
|
+
"""
|
217
|
+
global_object_square_logger.logger.error(e, exc_info=True)
|
218
|
+
output_content = get_api_output_in_standard_format(
|
219
|
+
message=messages["GENERIC_500"],
|
220
|
+
log=str(e),
|
221
|
+
)
|
222
|
+
return JSONResponse(
|
223
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
224
|
+
content=output_content,
|
225
|
+
)
|
226
|
+
|
227
|
+
|
228
|
+
@router.patch("/update_user_app_ids/v0")
|
229
|
+
@global_object_square_logger.async_auto_logger
|
230
|
+
async def update_user_app_ids_v0(
|
231
|
+
user_id: UUID,
|
232
|
+
app_ids_to_add: List[int],
|
233
|
+
app_ids_to_remove: List[int],
|
234
|
+
):
|
235
|
+
try:
|
236
|
+
local_string_user_id = str(user_id)
|
237
|
+
"""
|
238
|
+
validation
|
239
|
+
"""
|
240
|
+
|
241
|
+
app_ids_to_add = list(set(app_ids_to_add))
|
242
|
+
app_ids_to_remove = list(set(app_ids_to_remove))
|
243
|
+
|
244
|
+
# check if app_ids_to_add and app_ids_to_remove don't have common ids.
|
245
|
+
local_list_common_app_ids = set(app_ids_to_add) & set(app_ids_to_remove)
|
246
|
+
if len(local_list_common_app_ids) > 0:
|
247
|
+
output_content = get_api_output_in_standard_format(
|
248
|
+
message=messages["GENERIC_400"],
|
249
|
+
log=f"invalid app_ids: {list(local_list_common_app_ids)}, present in both add list and remove list.",
|
250
|
+
)
|
251
|
+
raise HTTPException(
|
252
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
253
|
+
detail=output_content,
|
254
|
+
)
|
255
|
+
# validate access token
|
256
|
+
# TBD
|
257
|
+
|
258
|
+
# check if user id is in user table
|
259
|
+
local_list_response_user = global_object_square_database_helper.get_rows_v0(
|
260
|
+
database_name=global_string_database_name,
|
261
|
+
schema_name=global_string_schema_name,
|
262
|
+
table_name=User.__tablename__,
|
263
|
+
filters=FiltersV0(
|
264
|
+
{User.user_id.name: FilterConditionsV0(eq=local_string_user_id)}
|
265
|
+
),
|
266
|
+
)["data"]["main"]
|
267
|
+
if len(local_list_response_user) != 1:
|
268
|
+
output_content = get_api_output_in_standard_format(
|
269
|
+
message=messages["INCORRECT_USER_ID"],
|
270
|
+
log=f"invalid user_id: {local_string_user_id}",
|
271
|
+
)
|
272
|
+
raise HTTPException(
|
273
|
+
status_code=status.HTTP_404_NOT_FOUND,
|
274
|
+
detail=output_content,
|
275
|
+
)
|
276
|
+
|
277
|
+
# check if all app_ids are valid
|
278
|
+
local_list_all_app_ids = [*app_ids_to_add, *app_ids_to_remove]
|
279
|
+
local_list_response_app = global_object_square_database_helper.get_rows_v0(
|
280
|
+
database_name=global_string_database_name,
|
281
|
+
schema_name=global_string_public_schema_name,
|
282
|
+
table_name=App.__tablename__,
|
283
|
+
apply_filters=False,
|
284
|
+
filters=FiltersV0({}),
|
285
|
+
)["data"]["main"]
|
286
|
+
local_list_invalid_ids = [
|
287
|
+
x
|
288
|
+
for x in local_list_all_app_ids
|
289
|
+
if x not in [y[App.app_id.name] for y in local_list_response_app]
|
290
|
+
]
|
291
|
+
if len(local_list_invalid_ids) > 0:
|
292
|
+
output_content = get_api_output_in_standard_format(
|
293
|
+
message=messages["GENERIC_400"],
|
294
|
+
log=f"invalid app_ids: {local_list_invalid_ids}.",
|
295
|
+
)
|
296
|
+
raise HTTPException(
|
297
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
298
|
+
detail=output_content,
|
299
|
+
)
|
300
|
+
"""
|
301
|
+
main process
|
302
|
+
"""
|
303
|
+
# logic for adding new app_ids
|
304
|
+
local_list_response_user_app = global_object_square_database_helper.get_rows_v0(
|
305
|
+
database_name=global_string_database_name,
|
306
|
+
schema_name=global_string_schema_name,
|
307
|
+
table_name=UserApp.__tablename__,
|
308
|
+
filters=FiltersV0(
|
309
|
+
{UserApp.user_id.name: FilterConditionsV0(eq=local_string_user_id)}
|
310
|
+
),
|
311
|
+
)["data"]["main"]
|
312
|
+
local_list_new_app_ids = [
|
313
|
+
{
|
314
|
+
UserApp.user_id.name: local_string_user_id,
|
315
|
+
UserApp.app_id.name: x,
|
316
|
+
}
|
317
|
+
for x in app_ids_to_add
|
318
|
+
if x not in [y[UserApp.app_id.name] for y in local_list_response_user_app]
|
319
|
+
]
|
320
|
+
if len(local_list_new_app_ids) > 0:
|
321
|
+
global_object_square_database_helper.insert_rows_v0(
|
322
|
+
database_name=global_string_database_name,
|
323
|
+
schema_name=global_string_schema_name,
|
324
|
+
table_name=UserApp.__tablename__,
|
325
|
+
data=local_list_new_app_ids,
|
326
|
+
)
|
327
|
+
|
328
|
+
# logic for removing app_ids
|
329
|
+
for app_id in app_ids_to_remove:
|
330
|
+
global_object_square_database_helper.delete_rows_v0(
|
331
|
+
database_name=global_string_database_name,
|
332
|
+
schema_name=global_string_schema_name,
|
333
|
+
table_name=UserApp.__tablename__,
|
334
|
+
filters=FiltersV0(
|
335
|
+
{
|
336
|
+
UserApp.user_id.name: FilterConditionsV0(
|
337
|
+
eq=local_string_user_id
|
338
|
+
),
|
339
|
+
UserApp.app_id.name: FilterConditionsV0(eq=app_id),
|
340
|
+
}
|
341
|
+
),
|
342
|
+
)
|
343
|
+
global_object_square_database_helper.delete_rows_v0(
|
344
|
+
database_name=global_string_database_name,
|
345
|
+
schema_name=global_string_schema_name,
|
346
|
+
table_name=UserSession.__tablename__,
|
347
|
+
filters=FiltersV0(
|
348
|
+
{
|
349
|
+
UserSession.user_id.name: FilterConditionsV0(
|
350
|
+
eq=local_string_user_id
|
351
|
+
),
|
352
|
+
UserSession.app_id.name: FilterConditionsV0(eq=app_id),
|
353
|
+
}
|
354
|
+
),
|
355
|
+
)
|
356
|
+
|
357
|
+
"""
|
358
|
+
return value
|
359
|
+
"""
|
360
|
+
# get latest app ids
|
361
|
+
local_list_response_user_app = global_object_square_database_helper.get_rows_v0(
|
362
|
+
database_name=global_string_database_name,
|
363
|
+
schema_name=global_string_schema_name,
|
364
|
+
table_name=UserApp.__tablename__,
|
365
|
+
filters=FiltersV0(
|
366
|
+
{UserApp.user_id.name: FilterConditionsV0(eq=local_string_user_id)}
|
367
|
+
),
|
368
|
+
)["data"]["main"]
|
369
|
+
output_content = get_api_output_in_standard_format(
|
370
|
+
message=messages["GENERIC_UPDATE_SUCCESSFUL"],
|
371
|
+
data={
|
372
|
+
"main": [x[UserApp.app_id.name] for x in local_list_response_user_app]
|
373
|
+
},
|
374
|
+
)
|
375
|
+
return JSONResponse(
|
376
|
+
status_code=status.HTTP_200_OK,
|
377
|
+
content=output_content,
|
378
|
+
)
|
379
|
+
except HTTPException as http_exception:
|
380
|
+
return JSONResponse(
|
381
|
+
status_code=http_exception.status_code, content=http_exception.detail
|
382
|
+
)
|
383
|
+
except Exception as e:
|
384
|
+
"""
|
385
|
+
rollback logic
|
386
|
+
"""
|
387
|
+
global_object_square_logger.logger.error(e, exc_info=True)
|
388
|
+
output_content = get_api_output_in_standard_format(
|
389
|
+
message=messages["GENERIC_500"],
|
390
|
+
log=str(e),
|
391
|
+
)
|
392
|
+
return JSONResponse(
|
393
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
394
|
+
content=output_content,
|
395
|
+
)
|
90
396
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
397
|
+
|
398
|
+
@router.get("/login_username/v0")
|
399
|
+
@global_object_square_logger.async_auto_logger
|
400
|
+
async def login_username_v0(username: str, password: str, app_id: int):
|
401
|
+
username = username.lower()
|
402
|
+
try:
|
403
|
+
"""
|
404
|
+
validation
|
405
|
+
"""
|
406
|
+
# validation for username
|
407
|
+
local_list_authentication_user_response = global_object_square_database_helper.get_rows_v0(
|
408
|
+
database_name=global_string_database_name,
|
409
|
+
schema_name=global_string_schema_name,
|
410
|
+
table_name=UserCredential.__tablename__,
|
411
|
+
filters=FiltersV0(
|
412
|
+
{
|
413
|
+
UserCredential.user_credential_username.name: FilterConditionsV0(
|
414
|
+
eq=username
|
415
|
+
)
|
416
|
+
}
|
417
|
+
),
|
418
|
+
)[
|
419
|
+
"data"
|
420
|
+
][
|
421
|
+
"main"
|
422
|
+
]
|
423
|
+
if len(local_list_authentication_user_response) != 1:
|
424
|
+
output_content = get_api_output_in_standard_format(
|
425
|
+
message=messages["INCORRECT_USERNAME"],
|
426
|
+
log=f"incorrect username {username}",
|
427
|
+
)
|
428
|
+
return JSONResponse(
|
429
|
+
status_code=status.HTTP_400_BAD_REQUEST, content=output_content
|
430
|
+
)
|
431
|
+
# validate if app_id is assigned to user
|
432
|
+
# this will also validate if app_id is valid
|
433
|
+
local_dict_user = local_list_authentication_user_response[0]
|
434
|
+
local_str_user_id = local_dict_user[UserCredential.user_id.name]
|
435
|
+
local_list_user_app_response = global_object_square_database_helper.get_rows_v0(
|
436
|
+
database_name=global_string_database_name,
|
437
|
+
schema_name=global_string_schema_name,
|
438
|
+
table_name=UserApp.__tablename__,
|
439
|
+
filters=FiltersV0(
|
440
|
+
{
|
441
|
+
UserApp.user_id.name: FilterConditionsV0(eq=local_str_user_id),
|
442
|
+
UserApp.app_id.name: FilterConditionsV0(eq=app_id),
|
443
|
+
}
|
444
|
+
),
|
445
|
+
)["data"]["main"]
|
446
|
+
if len(local_list_user_app_response) != 1:
|
447
|
+
output_content = get_api_output_in_standard_format(
|
448
|
+
message=messages["GENERIC_400"],
|
449
|
+
log=f"user_id {local_str_user_id}({username}) not assigned to app {app_id}.",
|
450
|
+
)
|
451
|
+
return JSONResponse(
|
452
|
+
status_code=status.HTTP_400_BAD_REQUEST, content=output_content
|
453
|
+
)
|
454
|
+
|
455
|
+
# validate password
|
456
|
+
if not (
|
457
|
+
bcrypt.checkpw(
|
458
|
+
password.encode("utf-8"),
|
459
|
+
local_dict_user[
|
460
|
+
UserCredential.user_credential_hashed_password.name
|
461
|
+
].encode("utf-8"),
|
462
|
+
)
|
463
|
+
):
|
464
|
+
output_content = get_api_output_in_standard_format(
|
465
|
+
message=messages["INCORRECT_PASSWORD"],
|
466
|
+
log=f"incorrect password for user_id {local_str_user_id}({username}).",
|
467
|
+
)
|
468
|
+
return JSONResponse(
|
469
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
470
|
+
content=output_content,
|
471
|
+
)
|
472
|
+
"""
|
473
|
+
main process
|
474
|
+
"""
|
475
|
+
# return new access token and refresh token
|
95
476
|
|
96
477
|
# create access token
|
97
478
|
local_dict_access_token_payload = {
|
479
|
+
"app_id": app_id,
|
98
480
|
"user_id": local_str_user_id,
|
99
481
|
"exp": datetime.now(timezone.utc)
|
100
|
-
|
482
|
+
+ timedelta(minutes=config_int_access_token_valid_minutes),
|
101
483
|
}
|
102
484
|
local_str_access_token = jwt.encode(
|
103
|
-
local_dict_access_token_payload,
|
485
|
+
local_dict_access_token_payload,
|
486
|
+
config_str_secret_key_for_access_token,
|
104
487
|
)
|
105
488
|
|
106
489
|
# create refresh token
|
@@ -109,222 +492,141 @@ async def register_username(username: str, password: str):
|
|
109
492
|
)
|
110
493
|
|
111
494
|
local_dict_refresh_token_payload = {
|
495
|
+
"app_id": app_id,
|
112
496
|
"user_id": local_str_user_id,
|
113
497
|
"exp": local_object_refresh_token_expiry_time,
|
114
498
|
}
|
115
499
|
local_str_refresh_token = jwt.encode(
|
116
|
-
local_dict_refresh_token_payload,
|
500
|
+
local_dict_refresh_token_payload,
|
501
|
+
config_str_secret_key_for_refresh_token,
|
117
502
|
)
|
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
503
|
# entry in user session table
|
143
|
-
|
504
|
+
global_object_square_database_helper.insert_rows_v0(
|
144
505
|
data=[
|
145
506
|
{
|
146
507
|
UserSession.user_id.name: local_str_user_id,
|
508
|
+
UserSession.app_id.name: app_id,
|
147
509
|
UserSession.user_session_refresh_token.name: local_str_refresh_token,
|
148
510
|
UserSession.user_session_expiry_time.name: local_object_refresh_token_expiry_time.strftime(
|
149
511
|
"%Y-%m-%d %H:%M:%S.%f+00"
|
150
512
|
),
|
151
513
|
}
|
152
514
|
],
|
153
|
-
database_name=
|
154
|
-
schema_name=
|
515
|
+
database_name=global_string_database_name,
|
516
|
+
schema_name=global_string_schema_name,
|
155
517
|
table_name=UserSession.__tablename__,
|
156
518
|
)
|
157
|
-
|
158
|
-
return
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
"
|
163
|
-
|
519
|
+
"""
|
520
|
+
return value
|
521
|
+
"""
|
522
|
+
output_content = get_api_output_in_standard_format(
|
523
|
+
data={
|
524
|
+
"main": {
|
525
|
+
"user_id": local_str_user_id,
|
526
|
+
"access_token": local_str_access_token,
|
527
|
+
"refresh_token": local_str_refresh_token,
|
528
|
+
}
|
164
529
|
},
|
530
|
+
message=messages["LOGIN_SUCCESSFUL"],
|
165
531
|
)
|
166
|
-
except Exception as e:
|
167
|
-
global_object_square_logger.logger.error(e, exc_info=True)
|
168
|
-
if local_str_user_id:
|
169
|
-
global_object_square_database_helper.delete_rows(
|
170
|
-
database_name=local_string_database_name,
|
171
|
-
schema_name=local_string_schema_name,
|
172
|
-
table_name=User.__tablename__,
|
173
|
-
filters={User.user_id.name: local_str_user_id},
|
174
|
-
)
|
175
532
|
return JSONResponse(
|
176
|
-
status_code=status.
|
533
|
+
status_code=status.HTTP_200_OK,
|
534
|
+
content=output_content,
|
177
535
|
)
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
@global_object_square_logger.async_auto_logger
|
182
|
-
async def login_username(username: str, password: str):
|
183
|
-
try:
|
184
|
-
# ======================================================================================
|
185
|
-
# get entry from authentication_username table
|
186
|
-
local_list_authentication_user_response = (
|
187
|
-
global_object_square_database_helper.get_rows(
|
188
|
-
database_name=local_string_database_name,
|
189
|
-
schema_name=local_string_schema_name,
|
190
|
-
table_name=UserCredential.__tablename__,
|
191
|
-
filters={UserCredential.user_credential_username.name: username},
|
192
|
-
)
|
536
|
+
except HTTPException as http_exception:
|
537
|
+
return JSONResponse(
|
538
|
+
status_code=http_exception.status_code, content=http_exception.detail
|
193
539
|
)
|
194
|
-
# ======================================================================================
|
195
|
-
|
196
|
-
# ======================================================================================
|
197
|
-
# validate username
|
198
|
-
# ======================================================================================
|
199
|
-
if len(local_list_authentication_user_response) != 1:
|
200
|
-
return JSONResponse(
|
201
|
-
status_code=status.HTTP_400_BAD_REQUEST, content="incorrect username."
|
202
|
-
)
|
203
|
-
# ======================================================================================
|
204
|
-
# validate password
|
205
|
-
# ======================================================================================
|
206
|
-
else:
|
207
|
-
if not (
|
208
|
-
bcrypt.checkpw(
|
209
|
-
password.encode("utf-8"),
|
210
|
-
local_list_authentication_user_response[0][
|
211
|
-
UserCredential.user_credential_hashed_password.name
|
212
|
-
].encode("utf-8"),
|
213
|
-
)
|
214
|
-
):
|
215
|
-
return JSONResponse(
|
216
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
217
|
-
content="incorrect password.",
|
218
|
-
)
|
219
|
-
|
220
|
-
# ======================================================================================
|
221
|
-
# return new access token and refresh token
|
222
|
-
# ======================================================================================
|
223
|
-
else:
|
224
|
-
local_str_user_id = local_list_authentication_user_response[0][
|
225
|
-
UserCredential.user_id.name
|
226
|
-
]
|
227
|
-
# create access token
|
228
|
-
local_dict_access_token_payload = {
|
229
|
-
"user_id": local_str_user_id,
|
230
|
-
"exp": datetime.now(timezone.utc)
|
231
|
-
+ timedelta(minutes=config_int_access_token_valid_minutes),
|
232
|
-
}
|
233
|
-
local_str_access_token = jwt.encode(
|
234
|
-
local_dict_access_token_payload,
|
235
|
-
config_str_secret_key_for_access_token,
|
236
|
-
)
|
237
|
-
|
238
|
-
# create refresh token
|
239
|
-
local_object_refresh_token_expiry_time = datetime.now(
|
240
|
-
timezone.utc
|
241
|
-
) + timedelta(minutes=config_int_refresh_token_valid_minutes)
|
242
|
-
|
243
|
-
local_dict_refresh_token_payload = {
|
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
|
-
|
278
540
|
except Exception as e:
|
541
|
+
"""
|
542
|
+
rollback logic
|
543
|
+
"""
|
279
544
|
global_object_square_logger.logger.error(e, exc_info=True)
|
545
|
+
output_content = get_api_output_in_standard_format(
|
546
|
+
message=messages["GENERIC_500"],
|
547
|
+
log=str(e),
|
548
|
+
)
|
280
549
|
return JSONResponse(
|
281
|
-
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=
|
550
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
282
551
|
)
|
283
552
|
|
284
553
|
|
285
|
-
@router.get("/generate_access_token/")
|
554
|
+
@router.get("/generate_access_token/v0")
|
286
555
|
@global_object_square_logger.async_auto_logger
|
287
|
-
async def
|
288
|
-
|
556
|
+
async def generate_access_token_v0(
|
557
|
+
user_id: str, app_id: int, refresh_token: Annotated[str, Header()]
|
289
558
|
):
|
290
559
|
try:
|
291
|
-
|
560
|
+
"""
|
561
|
+
validation
|
562
|
+
"""
|
292
563
|
# validate user_id
|
293
|
-
local_list_user_response = global_object_square_database_helper.
|
294
|
-
database_name=
|
295
|
-
schema_name=
|
564
|
+
local_list_user_response = global_object_square_database_helper.get_rows_v0(
|
565
|
+
database_name=global_string_database_name,
|
566
|
+
schema_name=global_string_schema_name,
|
296
567
|
table_name=User.__tablename__,
|
297
|
-
filters={User.user_id.name: user_id},
|
298
|
-
)
|
568
|
+
filters=FiltersV0({User.user_id.name: FilterConditionsV0(eq=user_id)}),
|
569
|
+
)["data"]["main"]
|
299
570
|
|
300
571
|
if len(local_list_user_response) != 1:
|
572
|
+
output_content = get_api_output_in_standard_format(
|
573
|
+
message=messages["INCORRECT_USER_ID"],
|
574
|
+
log=f"incorrect user_id: {user_id}.",
|
575
|
+
)
|
301
576
|
return JSONResponse(
|
302
577
|
status_code=status.HTTP_400_BAD_REQUEST,
|
303
|
-
content=
|
578
|
+
content=output_content,
|
579
|
+
)
|
580
|
+
# validate if app_id is assigned to user
|
581
|
+
# this will also validate if app_id is valid
|
582
|
+
local_dict_user = local_list_user_response[0]
|
583
|
+
local_str_user_id = local_dict_user[User.user_id.name]
|
584
|
+
local_list_user_app_response = global_object_square_database_helper.get_rows_v0(
|
585
|
+
database_name=global_string_database_name,
|
586
|
+
schema_name=global_string_schema_name,
|
587
|
+
table_name=UserApp.__tablename__,
|
588
|
+
filters=FiltersV0(
|
589
|
+
{
|
590
|
+
UserApp.user_id.name: FilterConditionsV0(eq=local_str_user_id),
|
591
|
+
UserApp.app_id.name: FilterConditionsV0(eq=app_id),
|
592
|
+
}
|
593
|
+
),
|
594
|
+
)["data"]["main"]
|
595
|
+
if len(local_list_user_app_response) != 1:
|
596
|
+
output_content = get_api_output_in_standard_format(
|
597
|
+
message=messages["GENERIC_400"],
|
598
|
+
log=f"user_id {local_str_user_id} not assigned to app {app_id}.",
|
599
|
+
)
|
600
|
+
return JSONResponse(
|
601
|
+
status_code=status.HTTP_400_BAD_REQUEST, content=output_content
|
304
602
|
)
|
305
|
-
# ======================================================================================
|
306
|
-
|
307
|
-
# ======================================================================================
|
308
603
|
# validate refresh token
|
309
|
-
|
310
|
-
# validating if a session refresh token exists in the database.
|
604
|
+
# validating if a session refresh token exists in the database for provided app id.
|
311
605
|
local_list_user_session_response = (
|
312
|
-
global_object_square_database_helper.
|
313
|
-
database_name=
|
314
|
-
schema_name=
|
606
|
+
global_object_square_database_helper.get_rows_v0(
|
607
|
+
database_name=global_string_database_name,
|
608
|
+
schema_name=global_string_schema_name,
|
315
609
|
table_name=UserSession.__tablename__,
|
316
|
-
filters=
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
610
|
+
filters=FiltersV0(
|
611
|
+
{
|
612
|
+
UserSession.user_id.name: FilterConditionsV0(eq=user_id),
|
613
|
+
UserSession.user_session_refresh_token.name: FilterConditionsV0(
|
614
|
+
eq=refresh_token
|
615
|
+
),
|
616
|
+
UserSession.app_id.name: FilterConditionsV0(eq=app_id),
|
617
|
+
}
|
618
|
+
),
|
619
|
+
)["data"]["main"]
|
321
620
|
)
|
322
621
|
|
323
622
|
if len(local_list_user_session_response) != 1:
|
623
|
+
output_content = get_api_output_in_standard_format(
|
624
|
+
message=messages["INCORRECT_REFRESH_TOKEN"],
|
625
|
+
log=f"incorrect refresh token: {refresh_token} for user_id: {user_id} for app_id: {app_id}.",
|
626
|
+
)
|
324
627
|
return JSONResponse(
|
325
628
|
status_code=status.HTTP_400_BAD_REQUEST,
|
326
|
-
content=
|
327
|
-
f"for user_id: {user_id}.",
|
629
|
+
content=output_content,
|
328
630
|
)
|
329
631
|
# validating if the refresh token is valid, active and of the same user.
|
330
632
|
try:
|
@@ -332,133 +634,238 @@ async def generate_access_token(
|
|
332
634
|
refresh_token, config_str_secret_key_for_refresh_token
|
333
635
|
)
|
334
636
|
except Exception as error:
|
637
|
+
output_content = get_api_output_in_standard_format(
|
638
|
+
message=messages["INCORRECT_REFRESH_TOKEN"], log=str(error)
|
639
|
+
)
|
335
640
|
return JSONResponse(
|
336
641
|
status_code=status.HTTP_400_BAD_REQUEST,
|
337
|
-
content=
|
642
|
+
content=output_content,
|
338
643
|
)
|
339
644
|
|
340
645
|
if local_dict_refresh_token_payload["user_id"] != user_id:
|
646
|
+
output_content = get_api_output_in_standard_format(
|
647
|
+
message=messages["INCORRECT_REFRESH_TOKEN"],
|
648
|
+
log=f"refresh token and user_id mismatch.",
|
649
|
+
)
|
341
650
|
return JSONResponse(
|
342
651
|
status_code=status.HTTP_400_BAD_REQUEST,
|
343
|
-
content=
|
652
|
+
content=output_content,
|
344
653
|
)
|
345
|
-
|
346
|
-
|
347
|
-
|
654
|
+
if local_dict_refresh_token_payload["app_id"] != app_id:
|
655
|
+
output_content = get_api_output_in_standard_format(
|
656
|
+
message=messages["INCORRECT_REFRESH_TOKEN"],
|
657
|
+
log=f"refresh token and app_id mismatch.",
|
658
|
+
)
|
659
|
+
return JSONResponse(
|
660
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
661
|
+
content=output_content,
|
662
|
+
)
|
663
|
+
"""
|
664
|
+
main process
|
665
|
+
"""
|
348
666
|
# create and send access token
|
349
667
|
local_dict_access_token_payload = {
|
668
|
+
"app_id": app_id,
|
350
669
|
"user_id": user_id,
|
351
670
|
"exp": datetime.now(timezone.utc)
|
352
|
-
|
671
|
+
+ timedelta(minutes=config_int_access_token_valid_minutes),
|
353
672
|
}
|
354
673
|
local_str_access_token = jwt.encode(
|
355
674
|
local_dict_access_token_payload, config_str_secret_key_for_access_token
|
356
675
|
)
|
357
|
-
|
676
|
+
"""
|
677
|
+
return value
|
678
|
+
"""
|
679
|
+
output_content = get_api_output_in_standard_format(
|
680
|
+
data={"main": {"access_token": local_str_access_token}},
|
681
|
+
message=messages["GENERIC_CREATION_SUCCESSFUL"],
|
682
|
+
)
|
358
683
|
return JSONResponse(
|
359
684
|
status_code=status.HTTP_200_OK,
|
360
|
-
content=
|
685
|
+
content=output_content,
|
686
|
+
)
|
687
|
+
except HTTPException as http_exception:
|
688
|
+
return JSONResponse(
|
689
|
+
status_code=http_exception.status_code, content=http_exception.detail
|
361
690
|
)
|
362
|
-
# ======================================================================================
|
363
|
-
|
364
691
|
except Exception as e:
|
692
|
+
"""
|
693
|
+
rollback logic
|
694
|
+
"""
|
365
695
|
global_object_square_logger.logger.error(e, exc_info=True)
|
696
|
+
output_content = get_api_output_in_standard_format(
|
697
|
+
message=messages["GENERIC_500"],
|
698
|
+
log=str(e),
|
699
|
+
)
|
366
700
|
return JSONResponse(
|
367
|
-
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=
|
701
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
368
702
|
)
|
369
703
|
|
370
704
|
|
371
|
-
@router.delete("/logout/")
|
705
|
+
@router.delete("/logout/v0")
|
372
706
|
@global_object_square_logger.async_auto_logger
|
373
|
-
async def
|
374
|
-
|
375
|
-
|
376
|
-
|
707
|
+
async def logout_v0(
|
708
|
+
user_id: str,
|
709
|
+
app_id: int,
|
710
|
+
access_token: Annotated[str, Header()],
|
711
|
+
refresh_token: Annotated[str, Header()],
|
377
712
|
):
|
378
713
|
try:
|
379
|
-
|
714
|
+
"""
|
715
|
+
validation
|
716
|
+
"""
|
380
717
|
# validate user_id
|
381
|
-
local_list_user_response = global_object_square_database_helper.
|
382
|
-
database_name=
|
383
|
-
schema_name=
|
718
|
+
local_list_user_response = global_object_square_database_helper.get_rows_v0(
|
719
|
+
database_name=global_string_database_name,
|
720
|
+
schema_name=global_string_schema_name,
|
384
721
|
table_name=User.__tablename__,
|
385
|
-
filters=
|
386
|
-
|
722
|
+
filters=FiltersV0(
|
723
|
+
{
|
724
|
+
User.user_id.name: FilterConditionsV0(eq=user_id),
|
725
|
+
}
|
726
|
+
),
|
727
|
+
)["data"]["main"]
|
387
728
|
|
388
729
|
if len(local_list_user_response) != 1:
|
730
|
+
output_content = get_api_output_in_standard_format(
|
731
|
+
message=messages["INCORRECT_USER_ID"],
|
732
|
+
log=f"incorrect user_id: {user_id}.",
|
733
|
+
)
|
389
734
|
return JSONResponse(
|
390
735
|
status_code=status.HTTP_400_BAD_REQUEST,
|
391
|
-
content=
|
736
|
+
content=output_content,
|
392
737
|
)
|
393
|
-
# ======================================================================================
|
394
738
|
|
395
|
-
#
|
396
|
-
# validate
|
739
|
+
# validate if app_id is assigned to user
|
740
|
+
# this will also validate if app_id is valid
|
741
|
+
local_dict_user = local_list_user_response[0]
|
742
|
+
local_str_user_id = local_dict_user[User.user_id.name]
|
743
|
+
local_list_user_app_response = global_object_square_database_helper.get_rows_v0(
|
744
|
+
database_name=global_string_database_name,
|
745
|
+
schema_name=global_string_schema_name,
|
746
|
+
table_name=UserApp.__tablename__,
|
747
|
+
filters=FiltersV0(
|
748
|
+
{
|
749
|
+
UserApp.user_id.name: FilterConditionsV0(eq=local_str_user_id),
|
750
|
+
UserApp.app_id.name: FilterConditionsV0(eq=app_id),
|
751
|
+
}
|
752
|
+
),
|
753
|
+
)["data"]["main"]
|
754
|
+
if len(local_list_user_app_response) != 1:
|
755
|
+
output_content = get_api_output_in_standard_format(
|
756
|
+
message=messages["GENERIC_400"],
|
757
|
+
log=f"user_id {local_str_user_id} not assigned to app {app_id}.",
|
758
|
+
)
|
759
|
+
return JSONResponse(
|
760
|
+
status_code=status.HTTP_400_BAD_REQUEST, content=output_content
|
761
|
+
)
|
397
762
|
|
763
|
+
# validate refresh token
|
398
764
|
# validating if a session refresh token exists in the database.
|
399
765
|
local_list_user_session_response = (
|
400
|
-
global_object_square_database_helper.
|
401
|
-
database_name=
|
402
|
-
schema_name=
|
766
|
+
global_object_square_database_helper.get_rows_v0(
|
767
|
+
database_name=global_string_database_name,
|
768
|
+
schema_name=global_string_schema_name,
|
403
769
|
table_name=UserSession.__tablename__,
|
404
|
-
filters=
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
770
|
+
filters=FiltersV0(
|
771
|
+
{
|
772
|
+
UserSession.user_id.name: FilterConditionsV0(eq=user_id),
|
773
|
+
UserSession.user_session_refresh_token.name: FilterConditionsV0(
|
774
|
+
eq=refresh_token
|
775
|
+
),
|
776
|
+
UserSession.app_id.name: FilterConditionsV0(eq=app_id),
|
777
|
+
}
|
778
|
+
),
|
779
|
+
)["data"]["main"]
|
409
780
|
)
|
410
781
|
|
411
782
|
if len(local_list_user_session_response) != 1:
|
783
|
+
output_content = get_api_output_in_standard_format(
|
784
|
+
message=messages["INCORRECT_REFRESH_TOKEN"],
|
785
|
+
log=f"incorrect refresh token: {refresh_token} for user_id: {user_id} for app_id: {app_id}.",
|
786
|
+
)
|
412
787
|
return JSONResponse(
|
413
788
|
status_code=status.HTTP_400_BAD_REQUEST,
|
414
|
-
content=
|
415
|
-
f"for user_id: {user_id}.",
|
789
|
+
content=output_content,
|
416
790
|
)
|
417
|
-
# not validating if the refresh token is valid, active and of the
|
418
|
-
# ======================================================================================
|
791
|
+
# **not validating if the refresh token is valid, active, of the same user and of the provided app id.**
|
419
792
|
|
420
|
-
# ======================================================================================
|
421
793
|
# validate access token
|
422
|
-
# validating if the access token is valid, active and of the
|
794
|
+
# validating if the access token is valid, active, of the same user and of the provided app.
|
423
795
|
try:
|
424
796
|
local_dict_access_token_payload = get_jwt_payload(
|
425
797
|
access_token, config_str_secret_key_for_access_token
|
426
798
|
)
|
427
799
|
except Exception as error:
|
800
|
+
output_content = get_api_output_in_standard_format(
|
801
|
+
message=messages["INCORRECT_ACCESS_TOKEN"], log=str(error)
|
802
|
+
)
|
428
803
|
return JSONResponse(
|
429
804
|
status_code=status.HTTP_400_BAD_REQUEST,
|
430
|
-
content=
|
805
|
+
content=output_content,
|
431
806
|
)
|
432
807
|
if local_dict_access_token_payload["user_id"] != user_id:
|
808
|
+
output_content = get_api_output_in_standard_format(
|
809
|
+
message=messages["INCORRECT_ACCESS_TOKEN"],
|
810
|
+
log=f"access token and user_id mismatch.",
|
811
|
+
)
|
433
812
|
return JSONResponse(
|
434
813
|
status_code=status.HTTP_400_BAD_REQUEST,
|
435
|
-
content=
|
814
|
+
content=output_content,
|
815
|
+
)
|
816
|
+
if local_dict_access_token_payload["app_id"] != app_id:
|
817
|
+
output_content = get_api_output_in_standard_format(
|
818
|
+
message=messages["INCORRECT_ACCESS_TOKEN"],
|
819
|
+
log=f"access token and app_id mismatch.",
|
820
|
+
)
|
821
|
+
return JSONResponse(
|
822
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
823
|
+
content=output_content,
|
436
824
|
)
|
437
|
-
|
438
825
|
# ======================================================================================
|
439
826
|
|
440
827
|
# NOTE: if both access token and refresh token have expired for a user,
|
441
828
|
# it can be assumed that user session only needs to be removed from the front end.
|
442
829
|
|
443
830
|
# ======================================================================================
|
831
|
+
"""
|
832
|
+
main process
|
833
|
+
"""
|
444
834
|
# delete session for user
|
445
|
-
global_object_square_database_helper.
|
446
|
-
database_name=
|
447
|
-
schema_name=
|
835
|
+
global_object_square_database_helper.delete_rows_v0(
|
836
|
+
database_name=global_string_database_name,
|
837
|
+
schema_name=global_string_schema_name,
|
448
838
|
table_name=UserSession.__tablename__,
|
449
|
-
filters=
|
450
|
-
|
451
|
-
|
452
|
-
|
839
|
+
filters=FiltersV0(
|
840
|
+
{
|
841
|
+
UserSession.user_id.name: FilterConditionsV0(eq=user_id),
|
842
|
+
UserSession.user_session_refresh_token.name: FilterConditionsV0(
|
843
|
+
eq=refresh_token
|
844
|
+
),
|
845
|
+
UserSession.app_id.name: FilterConditionsV0(eq=app_id),
|
846
|
+
}
|
847
|
+
),
|
453
848
|
)
|
454
|
-
|
849
|
+
"""
|
850
|
+
return value
|
851
|
+
"""
|
852
|
+
output_content = get_api_output_in_standard_format(
|
853
|
+
message=messages["LOGOUT_SUCCESSFUL"],
|
854
|
+
)
|
855
|
+
return JSONResponse(status_code=status.HTTP_200_OK, content=output_content)
|
856
|
+
except HTTPException as http_exception:
|
455
857
|
return JSONResponse(
|
456
|
-
status_code=
|
858
|
+
status_code=http_exception.status_code, content=http_exception.detail
|
457
859
|
)
|
458
|
-
# ======================================================================================
|
459
|
-
|
460
860
|
except Exception as e:
|
861
|
+
"""
|
862
|
+
rollback logic
|
863
|
+
"""
|
461
864
|
global_object_square_logger.logger.error(e, exc_info=True)
|
865
|
+
output_content = get_api_output_in_standard_format(
|
866
|
+
message=messages["GENERIC_500"],
|
867
|
+
log=str(e),
|
868
|
+
)
|
462
869
|
return JSONResponse(
|
463
|
-
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=
|
870
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
464
871
|
)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: square-authentication
|
3
|
-
Version:
|
3
|
+
Version: 2.0.0
|
4
4
|
Summary: authentication layer for my personal server.
|
5
5
|
Home-page: https://github.com/thepmsquare/square_authentication
|
6
6
|
Author: thePmSquare
|
@@ -20,10 +20,10 @@ Requires-Dist: bcrypt>=4.1.2
|
|
20
20
|
Requires-Dist: pyjwt>=2.8.0
|
21
21
|
Requires-Dist: requests>=2.32.3
|
22
22
|
Requires-Dist: cryptography>=42.0.7
|
23
|
-
Requires-Dist: square-commons>=0.0
|
23
|
+
Requires-Dist: square-commons>=1.0.0
|
24
24
|
Requires-Dist: square-logger>=1.0.0
|
25
|
-
Requires-Dist: square-database-helper>=0.0
|
26
|
-
Requires-Dist: square-database-structure>=0.0
|
25
|
+
Requires-Dist: square-database-helper>=2.0.0
|
26
|
+
Requires-Dist: square-database-structure>=1.0.0
|
27
27
|
|
28
28
|
# square_authentication
|
29
29
|
|
@@ -43,6 +43,21 @@ pip install square_authentication
|
|
43
43
|
|
44
44
|
## changelog
|
45
45
|
|
46
|
+
### v2.0.0
|
47
|
+
|
48
|
+
- authentication module needs to be used across applications so
|
49
|
+
- register_username: will not create sessions and therefore will not auto login.
|
50
|
+
- login: added validation if app is assigned to user before assigning it and added app_id in session row.
|
51
|
+
- logout: added app_id as new parameter and validation for that.
|
52
|
+
- generate_access_token: added app_id as new parameter and validation for that.
|
53
|
+
- added 2 new endpoints
|
54
|
+
- get user app ids: **access token validation pending**.
|
55
|
+
- change user app ids: **access token validation pending**.
|
56
|
+
- add versions for all endpoint paths.
|
57
|
+
- make it compatible with square_database_helper 2.x.
|
58
|
+
- username in database will always be lowercase.
|
59
|
+
- standardise output formats for all api.
|
60
|
+
|
46
61
|
### v1.0.0
|
47
62
|
|
48
63
|
- initial implementation.
|
@@ -0,0 +1,15 @@
|
|
1
|
+
square_authentication/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
+
square_authentication/configuration.py,sha256=i0uNtNSQd-n1rBxFM6jsIz1Wy3d090RcdTViSqHKc7Y,2973
|
3
|
+
square_authentication/main.py,sha256=JK9KBmN73KL8EpKrXrjrwwf37bmC4AXrFHtfl2roYwQ,1636
|
4
|
+
square_authentication/messages.py,sha256=NHJLnaB-qj69VJrMkmbMXDHJUnakQLht14ZBrw4dGgg,1094
|
5
|
+
square_authentication/data/config.ini,sha256=_740RvKpL5W2bUDGwZ7ePwuP-mAasr5cXXB81yq_Jv8,906
|
6
|
+
square_authentication/routes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
7
|
+
square_authentication/routes/core.py,sha256=gwfNQcMvT5DdbZQBotLPwy1Actr7SBSgrimfHfMviYs,33617
|
8
|
+
square_authentication/routes/utility.py,sha256=Kx4S4tZ1GKsPoC8CoZ4fkLEebvr02KeFEPePtTHtpnQ,75
|
9
|
+
square_authentication/utils/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
10
|
+
square_authentication/utils/encryption.py,sha256=T6BShoUr_xeGpbfPgTK-GxTlXPwcjwU4c4KW7KPzrF8,1865
|
11
|
+
square_authentication/utils/token.py,sha256=Y_arg5LegX-aprMj9YweUK8jjNZLGDjLUGgxbUA12w4,560
|
12
|
+
square_authentication-2.0.0.dist-info/METADATA,sha256=BrxsipcwD1dQNTUeM7pXXtAOZMPXBO1i4n7tRRbXx7s,1966
|
13
|
+
square_authentication-2.0.0.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
|
14
|
+
square_authentication-2.0.0.dist-info/top_level.txt,sha256=wDssVJIl9KIEJPj5rR3rv4uRI7yCndMBrvHd_6BGXQA,22
|
15
|
+
square_authentication-2.0.0.dist-info/RECORD,,
|
@@ -1,14 +0,0 @@
|
|
1
|
-
square_authentication/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
square_authentication/configuration.py,sha256=9rRznQcfsUd_o-OnYjdBJSiLa30_5o5BXJjzhZPLUqc,2993
|
3
|
-
square_authentication/main.py,sha256=01bu19koJNkJoz2VadPiV9M6TaIRoFEs5UabJfD6Tjo,1528
|
4
|
-
square_authentication/data/config.ini,sha256=_740RvKpL5W2bUDGwZ7ePwuP-mAasr5cXXB81yq_Jv8,906
|
5
|
-
square_authentication/routes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
6
|
-
square_authentication/routes/core.py,sha256=cZduu9VUMrrkrBYsR9elorQ6aPqpVAkV2f_4P8tKEto,20210
|
7
|
-
square_authentication/routes/utility.py,sha256=qFvXfmWqBhUAEQQq9StmY9tERVUoVE7Fe07dhVPZPoU,70
|
8
|
-
square_authentication/utils/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
9
|
-
square_authentication/utils/encryption.py,sha256=T6BShoUr_xeGpbfPgTK-GxTlXPwcjwU4c4KW7KPzrF8,1865
|
10
|
-
square_authentication/utils/token.py,sha256=Y_arg5LegX-aprMj9YweUK8jjNZLGDjLUGgxbUA12w4,560
|
11
|
-
square_authentication-1.0.0.dist-info/METADATA,sha256=vBdyC4c-vg7SWkg4GnxnAOtoRVPmAGzNBa4nD8LU60U,1209
|
12
|
-
square_authentication-1.0.0.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
|
13
|
-
square_authentication-1.0.0.dist-info/top_level.txt,sha256=wDssVJIl9KIEJPj5rR3rv4uRI7yCndMBrvHd_6BGXQA,22
|
14
|
-
square_authentication-1.0.0.dist-info/RECORD,,
|
File without changes
|
{square_authentication-1.0.0.dist-info → square_authentication-2.0.0.dist-info}/top_level.txt
RENAMED
File without changes
|