square-authentication 2.0.0__py3-none-any.whl → 4.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/messages.py +2 -1
- square_authentication/pydantic_models/__init__.py +0 -0
- square_authentication/pydantic_models/core.py +25 -0
- square_authentication/routes/core.py +519 -194
- {square_authentication-2.0.0.dist-info → square_authentication-4.0.0.dist-info}/METADATA +20 -1
- {square_authentication-2.0.0.dist-info → square_authentication-4.0.0.dist-info}/RECORD +8 -6
- {square_authentication-2.0.0.dist-info → square_authentication-4.0.0.dist-info}/WHEEL +1 -1
- {square_authentication-2.0.0.dist-info → square_authentication-4.0.0.dist-info}/top_level.txt +0 -0
@@ -8,9 +8,10 @@ messages = {
|
|
8
8
|
"USERNAME_ALREADY_EXISTS": "the username you entered is already taken. please choose a different one.",
|
9
9
|
"INCORRECT_ACCESS_TOKEN": "the access token provided is invalid or expired.",
|
10
10
|
"INCORRECT_REFRESH_TOKEN": "the refresh token provided is invalid or expired.",
|
11
|
-
"GENERIC_READ_SUCCESSFUL": "data retrieved successfully.",
|
12
11
|
"GENERIC_CREATION_SUCCESSFUL": "records created successfully.",
|
12
|
+
"GENERIC_READ_SUCCESSFUL": "data retrieved successfully.",
|
13
13
|
"GENERIC_UPDATE_SUCCESSFUL": "your information has been updated successfully.",
|
14
|
+
"GENERIC_DELETE_SUCCESSFUL": "your records have been deleted successfully.",
|
14
15
|
"GENERIC_400": "the request is invalid or cannot be processed.",
|
15
16
|
"GENERIC_500": "an internal server error occurred. please try again later.",
|
16
17
|
}
|
File without changes
|
@@ -0,0 +1,25 @@
|
|
1
|
+
from typing import Optional
|
2
|
+
|
3
|
+
from pydantic import BaseModel
|
4
|
+
|
5
|
+
|
6
|
+
class RegisterUsernameV0(BaseModel):
|
7
|
+
username: str
|
8
|
+
password: str
|
9
|
+
app_id: Optional[int] = None
|
10
|
+
|
11
|
+
|
12
|
+
class LoginUsernameV0(BaseModel):
|
13
|
+
username: str
|
14
|
+
password: str
|
15
|
+
app_id: int
|
16
|
+
assign_app_id_if_missing: bool = False
|
17
|
+
|
18
|
+
|
19
|
+
class DeleteUserV0(BaseModel):
|
20
|
+
password: str
|
21
|
+
|
22
|
+
|
23
|
+
class UpdatePasswordV0(BaseModel):
|
24
|
+
old_password: str
|
25
|
+
new_password: str
|
@@ -1,11 +1,11 @@
|
|
1
1
|
from datetime import datetime, timedelta, timezone
|
2
2
|
from typing import Annotated, List
|
3
|
-
from uuid import UUID
|
4
3
|
|
5
4
|
import bcrypt
|
6
5
|
import jwt
|
7
6
|
from fastapi import APIRouter, status, Header, HTTPException
|
8
7
|
from fastapi.responses import JSONResponse
|
8
|
+
from requests import HTTPError
|
9
9
|
from square_commons import get_api_output_in_standard_format
|
10
10
|
from square_database.pydantic_models.pydantic_models import (
|
11
11
|
FiltersV0,
|
@@ -36,6 +36,12 @@ from square_authentication.configuration import (
|
|
36
36
|
config_str_square_database_protocol,
|
37
37
|
)
|
38
38
|
from square_authentication.messages import messages
|
39
|
+
from square_authentication.pydantic_models.core import (
|
40
|
+
RegisterUsernameV0,
|
41
|
+
LoginUsernameV0,
|
42
|
+
DeleteUserV0,
|
43
|
+
UpdatePasswordV0,
|
44
|
+
)
|
39
45
|
from square_authentication.utils.token import get_jwt_payload
|
40
46
|
|
41
47
|
router = APIRouter(
|
@@ -51,8 +57,17 @@ global_object_square_database_helper = SquareDatabaseHelper(
|
|
51
57
|
|
52
58
|
@router.post("/register_username/v0")
|
53
59
|
@global_object_square_logger.async_auto_logger
|
54
|
-
async def register_username_v0(
|
60
|
+
async def register_username_v0(
|
61
|
+
body: RegisterUsernameV0,
|
62
|
+
):
|
63
|
+
username = body.username
|
64
|
+
password = body.password
|
65
|
+
app_id = body.app_id
|
66
|
+
|
55
67
|
local_str_user_id = None
|
68
|
+
local_str_access_token = None
|
69
|
+
local_str_refresh_token = None
|
70
|
+
|
56
71
|
username = username.lower()
|
57
72
|
try:
|
58
73
|
"""
|
@@ -117,13 +132,77 @@ async def register_username_v0(username: str, password: str):
|
|
117
132
|
schema_name=global_string_schema_name,
|
118
133
|
table_name=UserCredential.__tablename__,
|
119
134
|
)
|
135
|
+
if app_id is not None:
|
136
|
+
# assign app to user
|
137
|
+
global_object_square_database_helper.insert_rows_v0(
|
138
|
+
database_name=global_string_database_name,
|
139
|
+
schema_name=global_string_schema_name,
|
140
|
+
table_name=UserApp.__tablename__,
|
141
|
+
data=[
|
142
|
+
{
|
143
|
+
UserApp.user_id.name: local_str_user_id,
|
144
|
+
UserApp.app_id.name: app_id,
|
145
|
+
}
|
146
|
+
],
|
147
|
+
)
|
148
|
+
|
149
|
+
# return new access token and refresh token
|
150
|
+
# create access token
|
151
|
+
local_dict_access_token_payload = {
|
152
|
+
"app_id": app_id,
|
153
|
+
"user_id": local_str_user_id,
|
154
|
+
"exp": datetime.now(timezone.utc)
|
155
|
+
+ timedelta(minutes=config_int_access_token_valid_minutes),
|
156
|
+
}
|
157
|
+
local_str_access_token = jwt.encode(
|
158
|
+
local_dict_access_token_payload,
|
159
|
+
config_str_secret_key_for_access_token,
|
160
|
+
)
|
120
161
|
|
162
|
+
# create refresh token
|
163
|
+
local_object_refresh_token_expiry_time = datetime.now(
|
164
|
+
timezone.utc
|
165
|
+
) + timedelta(minutes=config_int_refresh_token_valid_minutes)
|
166
|
+
|
167
|
+
local_dict_refresh_token_payload = {
|
168
|
+
"app_id": app_id,
|
169
|
+
"user_id": local_str_user_id,
|
170
|
+
"exp": local_object_refresh_token_expiry_time,
|
171
|
+
}
|
172
|
+
local_str_refresh_token = jwt.encode(
|
173
|
+
local_dict_refresh_token_payload,
|
174
|
+
config_str_secret_key_for_refresh_token,
|
175
|
+
)
|
176
|
+
# entry in user session table
|
177
|
+
global_object_square_database_helper.insert_rows_v0(
|
178
|
+
data=[
|
179
|
+
{
|
180
|
+
UserSession.user_id.name: local_str_user_id,
|
181
|
+
UserSession.app_id.name: app_id,
|
182
|
+
UserSession.user_session_refresh_token.name: local_str_refresh_token,
|
183
|
+
UserSession.user_session_expiry_time.name: local_object_refresh_token_expiry_time.strftime(
|
184
|
+
"%Y-%m-%d %H:%M:%S.%f+00"
|
185
|
+
),
|
186
|
+
}
|
187
|
+
],
|
188
|
+
database_name=global_string_database_name,
|
189
|
+
schema_name=global_string_schema_name,
|
190
|
+
table_name=UserSession.__tablename__,
|
191
|
+
)
|
121
192
|
"""
|
122
193
|
return value
|
123
194
|
"""
|
124
195
|
output_content = get_api_output_in_standard_format(
|
125
196
|
message=messages["REGISTRATION_SUCCESSFUL"],
|
126
|
-
data={
|
197
|
+
data={
|
198
|
+
"main": {
|
199
|
+
"user_id": local_str_user_id,
|
200
|
+
"username": username,
|
201
|
+
"app_id": app_id,
|
202
|
+
"access_token": local_str_access_token,
|
203
|
+
"refresh_token": local_str_refresh_token,
|
204
|
+
},
|
205
|
+
},
|
127
206
|
)
|
128
207
|
return JSONResponse(
|
129
208
|
status_code=status.HTTP_201_CREATED,
|
@@ -156,32 +235,29 @@ async def register_username_v0(username: str, password: str):
|
|
156
235
|
)
|
157
236
|
|
158
237
|
|
159
|
-
@router.get("/
|
238
|
+
@router.get("/get_user_details/v0")
|
160
239
|
@global_object_square_logger.async_auto_logger
|
161
|
-
async def
|
240
|
+
async def get_user_details_v0(
|
241
|
+
access_token: Annotated[str, Header()],
|
242
|
+
):
|
162
243
|
try:
|
163
|
-
local_string_user_id = str(user_id)
|
164
244
|
"""
|
165
245
|
validation
|
166
246
|
"""
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
{User.user_id.name: FilterConditionsV0(eq=local_string_user_id)}
|
174
|
-
),
|
175
|
-
)["data"]["main"]
|
176
|
-
if len(local_list_response_user) != 1:
|
247
|
+
# validate access token
|
248
|
+
try:
|
249
|
+
local_dict_access_token_payload = get_jwt_payload(
|
250
|
+
access_token, config_str_secret_key_for_access_token
|
251
|
+
)
|
252
|
+
except Exception as error:
|
177
253
|
output_content = get_api_output_in_standard_format(
|
178
|
-
message=messages["
|
179
|
-
log=f"invalid user_id: {local_string_user_id}",
|
254
|
+
message=messages["INCORRECT_ACCESS_TOKEN"], log=str(error)
|
180
255
|
)
|
181
|
-
|
182
|
-
status_code=status.
|
183
|
-
|
256
|
+
return JSONResponse(
|
257
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
258
|
+
content=output_content,
|
184
259
|
)
|
260
|
+
user_id = local_dict_access_token_payload["user_id"]
|
185
261
|
"""
|
186
262
|
main process
|
187
263
|
"""
|
@@ -189,18 +265,61 @@ async def get_user_app_ids_v0(user_id: UUID):
|
|
189
265
|
database_name=global_string_database_name,
|
190
266
|
schema_name=global_string_schema_name,
|
191
267
|
table_name=UserApp.__tablename__,
|
192
|
-
filters=FiltersV0(
|
193
|
-
{UserApp.user_id.name: FilterConditionsV0(eq=local_string_user_id)}
|
194
|
-
),
|
268
|
+
filters=FiltersV0({UserApp.user_id.name: FilterConditionsV0(eq=user_id)}),
|
195
269
|
)["data"]["main"]
|
270
|
+
local_list_response_user_credentials = (
|
271
|
+
global_object_square_database_helper.get_rows_v0(
|
272
|
+
database_name=global_string_database_name,
|
273
|
+
schema_name=global_string_schema_name,
|
274
|
+
table_name=UserCredential.__tablename__,
|
275
|
+
filters=FiltersV0(
|
276
|
+
{UserCredential.user_id.name: FilterConditionsV0(eq=user_id)}
|
277
|
+
),
|
278
|
+
)["data"]["main"]
|
279
|
+
)
|
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
|
+
UserSession.user_session_expiry_time.name: FilterConditionsV0(
|
289
|
+
gte=datetime.now(timezone.utc).isoformat()
|
290
|
+
),
|
291
|
+
}
|
292
|
+
),
|
293
|
+
)["data"]["main"]
|
294
|
+
)
|
196
295
|
"""
|
197
296
|
return value
|
198
297
|
"""
|
298
|
+
return_this = {
|
299
|
+
"user_id": user_id,
|
300
|
+
"credentials": {
|
301
|
+
"username": local_list_response_user_credentials[0][
|
302
|
+
UserCredential.user_credential_username.name
|
303
|
+
],
|
304
|
+
},
|
305
|
+
"apps": [x[UserApp.app_id.name] for x in local_list_response_user_app],
|
306
|
+
"sessions": [
|
307
|
+
{
|
308
|
+
"app_id": x[UserApp.app_id.name],
|
309
|
+
"active_sessions": len(
|
310
|
+
[
|
311
|
+
y
|
312
|
+
for y in local_list_response_user_sessions
|
313
|
+
if y[UserSession.app_id.name] == x[UserApp.app_id.name]
|
314
|
+
]
|
315
|
+
),
|
316
|
+
}
|
317
|
+
for x in local_list_response_user_app
|
318
|
+
],
|
319
|
+
}
|
199
320
|
output_content = get_api_output_in_standard_format(
|
200
321
|
message=messages["GENERIC_READ_SUCCESSFUL"],
|
201
|
-
data={
|
202
|
-
"main": [x[UserApp.app_id.name] for x in local_list_response_user_app]
|
203
|
-
},
|
322
|
+
data={"main": return_this},
|
204
323
|
)
|
205
324
|
return JSONResponse(
|
206
325
|
status_code=status.HTTP_200_OK,
|
@@ -228,15 +347,29 @@ async def get_user_app_ids_v0(user_id: UUID):
|
|
228
347
|
@router.patch("/update_user_app_ids/v0")
|
229
348
|
@global_object_square_logger.async_auto_logger
|
230
349
|
async def update_user_app_ids_v0(
|
231
|
-
|
350
|
+
access_token: Annotated[str, Header()],
|
232
351
|
app_ids_to_add: List[int],
|
233
352
|
app_ids_to_remove: List[int],
|
234
353
|
):
|
235
354
|
try:
|
236
|
-
|
355
|
+
|
237
356
|
"""
|
238
357
|
validation
|
239
358
|
"""
|
359
|
+
# validate access token
|
360
|
+
try:
|
361
|
+
local_dict_access_token_payload = get_jwt_payload(
|
362
|
+
access_token, config_str_secret_key_for_access_token
|
363
|
+
)
|
364
|
+
except Exception as error:
|
365
|
+
output_content = get_api_output_in_standard_format(
|
366
|
+
message=messages["INCORRECT_ACCESS_TOKEN"], log=str(error)
|
367
|
+
)
|
368
|
+
return JSONResponse(
|
369
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
370
|
+
content=output_content,
|
371
|
+
)
|
372
|
+
user_id = local_dict_access_token_payload["user_id"]
|
240
373
|
|
241
374
|
app_ids_to_add = list(set(app_ids_to_add))
|
242
375
|
app_ids_to_remove = list(set(app_ids_to_remove))
|
@@ -252,27 +385,6 @@ async def update_user_app_ids_v0(
|
|
252
385
|
status_code=status.HTTP_400_BAD_REQUEST,
|
253
386
|
detail=output_content,
|
254
387
|
)
|
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
388
|
|
277
389
|
# check if all app_ids are valid
|
278
390
|
local_list_all_app_ids = [*app_ids_to_add, *app_ids_to_remove]
|
@@ -305,13 +417,11 @@ async def update_user_app_ids_v0(
|
|
305
417
|
database_name=global_string_database_name,
|
306
418
|
schema_name=global_string_schema_name,
|
307
419
|
table_name=UserApp.__tablename__,
|
308
|
-
filters=FiltersV0(
|
309
|
-
{UserApp.user_id.name: FilterConditionsV0(eq=local_string_user_id)}
|
310
|
-
),
|
420
|
+
filters=FiltersV0({UserApp.user_id.name: FilterConditionsV0(eq=user_id)}),
|
311
421
|
)["data"]["main"]
|
312
422
|
local_list_new_app_ids = [
|
313
423
|
{
|
314
|
-
UserApp.user_id.name:
|
424
|
+
UserApp.user_id.name: user_id,
|
315
425
|
UserApp.app_id.name: x,
|
316
426
|
}
|
317
427
|
for x in app_ids_to_add
|
@@ -333,22 +443,19 @@ async def update_user_app_ids_v0(
|
|
333
443
|
table_name=UserApp.__tablename__,
|
334
444
|
filters=FiltersV0(
|
335
445
|
{
|
336
|
-
UserApp.user_id.name: FilterConditionsV0(
|
337
|
-
eq=local_string_user_id
|
338
|
-
),
|
446
|
+
UserApp.user_id.name: FilterConditionsV0(eq=user_id),
|
339
447
|
UserApp.app_id.name: FilterConditionsV0(eq=app_id),
|
340
448
|
}
|
341
449
|
),
|
342
450
|
)
|
451
|
+
# logout user from removed apps
|
343
452
|
global_object_square_database_helper.delete_rows_v0(
|
344
453
|
database_name=global_string_database_name,
|
345
454
|
schema_name=global_string_schema_name,
|
346
455
|
table_name=UserSession.__tablename__,
|
347
456
|
filters=FiltersV0(
|
348
457
|
{
|
349
|
-
UserSession.user_id.name: FilterConditionsV0(
|
350
|
-
eq=local_string_user_id
|
351
|
-
),
|
458
|
+
UserSession.user_id.name: FilterConditionsV0(eq=user_id),
|
352
459
|
UserSession.app_id.name: FilterConditionsV0(eq=app_id),
|
353
460
|
}
|
354
461
|
),
|
@@ -362,9 +469,7 @@ async def update_user_app_ids_v0(
|
|
362
469
|
database_name=global_string_database_name,
|
363
470
|
schema_name=global_string_schema_name,
|
364
471
|
table_name=UserApp.__tablename__,
|
365
|
-
filters=FiltersV0(
|
366
|
-
{UserApp.user_id.name: FilterConditionsV0(eq=local_string_user_id)}
|
367
|
-
),
|
472
|
+
filters=FiltersV0({UserApp.user_id.name: FilterConditionsV0(eq=user_id)}),
|
368
473
|
)["data"]["main"]
|
369
474
|
output_content = get_api_output_in_standard_format(
|
370
475
|
message=messages["GENERIC_UPDATE_SUCCESSFUL"],
|
@@ -395,9 +500,13 @@ async def update_user_app_ids_v0(
|
|
395
500
|
)
|
396
501
|
|
397
502
|
|
398
|
-
@router.
|
503
|
+
@router.post("/login_username/v0")
|
399
504
|
@global_object_square_logger.async_auto_logger
|
400
|
-
async def login_username_v0(
|
505
|
+
async def login_username_v0(body: LoginUsernameV0):
|
506
|
+
username = body.username
|
507
|
+
password = body.password
|
508
|
+
app_id = body.app_id
|
509
|
+
assign_app_id_if_missing = body.assign_app_id_if_missing
|
401
510
|
username = username.lower()
|
402
511
|
try:
|
403
512
|
"""
|
@@ -443,14 +552,36 @@ async def login_username_v0(username: str, password: str, app_id: int):
|
|
443
552
|
}
|
444
553
|
),
|
445
554
|
)["data"]["main"]
|
446
|
-
if len(local_list_user_app_response)
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
555
|
+
if len(local_list_user_app_response) == 0:
|
556
|
+
if assign_app_id_if_missing:
|
557
|
+
try:
|
558
|
+
global_object_square_database_helper.insert_rows_v0(
|
559
|
+
database_name=global_string_database_name,
|
560
|
+
schema_name=global_string_schema_name,
|
561
|
+
table_name=UserApp.__tablename__,
|
562
|
+
data=[
|
563
|
+
{
|
564
|
+
UserApp.user_id.name: local_str_user_id,
|
565
|
+
UserApp.app_id.name: app_id,
|
566
|
+
}
|
567
|
+
],
|
568
|
+
)
|
569
|
+
except HTTPError as he:
|
570
|
+
output_content = get_api_output_in_standard_format(
|
571
|
+
message=messages["GENERIC_400"],
|
572
|
+
log=str(he),
|
573
|
+
)
|
574
|
+
return JSONResponse(
|
575
|
+
status_code=he.response.status_code, content=output_content
|
576
|
+
)
|
577
|
+
else:
|
578
|
+
output_content = get_api_output_in_standard_format(
|
579
|
+
message=messages["GENERIC_400"],
|
580
|
+
log=f"user_id {local_str_user_id}({username}) not assigned to app {app_id}.",
|
581
|
+
)
|
582
|
+
return JSONResponse(
|
583
|
+
status_code=status.HTTP_400_BAD_REQUEST, content=output_content
|
584
|
+
)
|
454
585
|
|
455
586
|
# validate password
|
456
587
|
if not (
|
@@ -554,54 +685,14 @@ async def login_username_v0(username: str, password: str, app_id: int):
|
|
554
685
|
@router.get("/generate_access_token/v0")
|
555
686
|
@global_object_square_logger.async_auto_logger
|
556
687
|
async def generate_access_token_v0(
|
557
|
-
|
688
|
+
refresh_token: Annotated[str, Header()],
|
558
689
|
):
|
559
690
|
try:
|
560
691
|
"""
|
561
692
|
validation
|
562
693
|
"""
|
563
|
-
# validate user_id
|
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,
|
567
|
-
table_name=User.__tablename__,
|
568
|
-
filters=FiltersV0({User.user_id.name: FilterConditionsV0(eq=user_id)}),
|
569
|
-
)["data"]["main"]
|
570
|
-
|
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
|
-
)
|
576
|
-
return JSONResponse(
|
577
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
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
|
602
|
-
)
|
603
694
|
# validate refresh token
|
604
|
-
# validating if a session refresh token exists in the database
|
695
|
+
# validating if a session refresh token exists in the database.
|
605
696
|
local_list_user_session_response = (
|
606
697
|
global_object_square_database_helper.get_rows_v0(
|
607
698
|
database_name=global_string_database_name,
|
@@ -609,11 +700,9 @@ async def generate_access_token_v0(
|
|
609
700
|
table_name=UserSession.__tablename__,
|
610
701
|
filters=FiltersV0(
|
611
702
|
{
|
612
|
-
UserSession.user_id.name: FilterConditionsV0(eq=user_id),
|
613
703
|
UserSession.user_session_refresh_token.name: FilterConditionsV0(
|
614
704
|
eq=refresh_token
|
615
705
|
),
|
616
|
-
UserSession.app_id.name: FilterConditionsV0(eq=app_id),
|
617
706
|
}
|
618
707
|
),
|
619
708
|
)["data"]["main"]
|
@@ -622,7 +711,7 @@ async def generate_access_token_v0(
|
|
622
711
|
if len(local_list_user_session_response) != 1:
|
623
712
|
output_content = get_api_output_in_standard_format(
|
624
713
|
message=messages["INCORRECT_REFRESH_TOKEN"],
|
625
|
-
log=f"incorrect refresh token: {refresh_token}
|
714
|
+
log=f"incorrect refresh token: {refresh_token}.",
|
626
715
|
)
|
627
716
|
return JSONResponse(
|
628
717
|
status_code=status.HTTP_400_BAD_REQUEST,
|
@@ -641,32 +730,13 @@ async def generate_access_token_v0(
|
|
641
730
|
status_code=status.HTTP_400_BAD_REQUEST,
|
642
731
|
content=output_content,
|
643
732
|
)
|
644
|
-
|
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
|
-
)
|
650
|
-
return JSONResponse(
|
651
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
652
|
-
content=output_content,
|
653
|
-
)
|
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
733
|
"""
|
664
734
|
main process
|
665
735
|
"""
|
666
736
|
# create and send access token
|
667
737
|
local_dict_access_token_payload = {
|
668
|
-
"app_id": app_id,
|
669
|
-
"user_id": user_id,
|
738
|
+
"app_id": local_dict_refresh_token_payload["app_id"],
|
739
|
+
"user_id": local_dict_refresh_token_payload["user_id"],
|
670
740
|
"exp": datetime.now(timezone.utc)
|
671
741
|
+ timedelta(minutes=config_int_access_token_valid_minutes),
|
672
742
|
}
|
@@ -705,15 +775,121 @@ async def generate_access_token_v0(
|
|
705
775
|
@router.delete("/logout/v0")
|
706
776
|
@global_object_square_logger.async_auto_logger
|
707
777
|
async def logout_v0(
|
708
|
-
user_id: str,
|
709
|
-
app_id: int,
|
710
|
-
access_token: Annotated[str, Header()],
|
711
778
|
refresh_token: Annotated[str, Header()],
|
712
779
|
):
|
713
780
|
try:
|
714
781
|
"""
|
715
782
|
validation
|
716
783
|
"""
|
784
|
+
# validate refresh token
|
785
|
+
# validating if a session refresh token exists in the database.
|
786
|
+
local_list_user_session_response = (
|
787
|
+
global_object_square_database_helper.get_rows_v0(
|
788
|
+
database_name=global_string_database_name,
|
789
|
+
schema_name=global_string_schema_name,
|
790
|
+
table_name=UserSession.__tablename__,
|
791
|
+
filters=FiltersV0(
|
792
|
+
{
|
793
|
+
UserSession.user_session_refresh_token.name: FilterConditionsV0(
|
794
|
+
eq=refresh_token
|
795
|
+
),
|
796
|
+
}
|
797
|
+
),
|
798
|
+
)["data"]["main"]
|
799
|
+
)
|
800
|
+
|
801
|
+
if len(local_list_user_session_response) != 1:
|
802
|
+
output_content = get_api_output_in_standard_format(
|
803
|
+
message=messages["INCORRECT_REFRESH_TOKEN"],
|
804
|
+
log=f"incorrect refresh token: {refresh_token}.",
|
805
|
+
)
|
806
|
+
return JSONResponse(
|
807
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
808
|
+
content=output_content,
|
809
|
+
)
|
810
|
+
# validating if the refresh token is valid, active and of the same user.
|
811
|
+
try:
|
812
|
+
local_dict_refresh_token_payload = get_jwt_payload(
|
813
|
+
refresh_token, config_str_secret_key_for_refresh_token
|
814
|
+
)
|
815
|
+
except Exception as error:
|
816
|
+
output_content = get_api_output_in_standard_format(
|
817
|
+
message=messages["INCORRECT_REFRESH_TOKEN"],
|
818
|
+
log=str(error),
|
819
|
+
)
|
820
|
+
return JSONResponse(
|
821
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
822
|
+
content=output_content,
|
823
|
+
)
|
824
|
+
# ======================================================================================
|
825
|
+
# NOTE: if refresh token has expired no need to delete it during this call
|
826
|
+
# ======================================================================================
|
827
|
+
"""
|
828
|
+
main process
|
829
|
+
"""
|
830
|
+
# delete session for user
|
831
|
+
global_object_square_database_helper.delete_rows_v0(
|
832
|
+
database_name=global_string_database_name,
|
833
|
+
schema_name=global_string_schema_name,
|
834
|
+
table_name=UserSession.__tablename__,
|
835
|
+
filters=FiltersV0(
|
836
|
+
{
|
837
|
+
UserSession.user_session_refresh_token.name: FilterConditionsV0(
|
838
|
+
eq=refresh_token
|
839
|
+
),
|
840
|
+
}
|
841
|
+
),
|
842
|
+
)
|
843
|
+
"""
|
844
|
+
return value
|
845
|
+
"""
|
846
|
+
output_content = get_api_output_in_standard_format(
|
847
|
+
message=messages["LOGOUT_SUCCESSFUL"],
|
848
|
+
)
|
849
|
+
return JSONResponse(status_code=status.HTTP_200_OK, content=output_content)
|
850
|
+
except HTTPException as http_exception:
|
851
|
+
return JSONResponse(
|
852
|
+
status_code=http_exception.status_code, content=http_exception.detail
|
853
|
+
)
|
854
|
+
except Exception as e:
|
855
|
+
"""
|
856
|
+
rollback logic
|
857
|
+
"""
|
858
|
+
global_object_square_logger.logger.error(e, exc_info=True)
|
859
|
+
output_content = get_api_output_in_standard_format(
|
860
|
+
message=messages["GENERIC_500"],
|
861
|
+
log=str(e),
|
862
|
+
)
|
863
|
+
return JSONResponse(
|
864
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
865
|
+
)
|
866
|
+
|
867
|
+
|
868
|
+
@router.patch("/update_username/v0")
|
869
|
+
@global_object_square_logger.async_auto_logger
|
870
|
+
async def update_username_v0(
|
871
|
+
new_username: str,
|
872
|
+
access_token: Annotated[str, Header()],
|
873
|
+
):
|
874
|
+
try:
|
875
|
+
"""
|
876
|
+
validation
|
877
|
+
"""
|
878
|
+
# validate access token
|
879
|
+
try:
|
880
|
+
local_dict_access_token_payload = get_jwt_payload(
|
881
|
+
access_token, config_str_secret_key_for_access_token
|
882
|
+
)
|
883
|
+
except Exception as error:
|
884
|
+
output_content = get_api_output_in_standard_format(
|
885
|
+
message=messages["INCORRECT_ACCESS_TOKEN"], log=str(error)
|
886
|
+
)
|
887
|
+
return JSONResponse(
|
888
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
889
|
+
content=output_content,
|
890
|
+
)
|
891
|
+
user_id = local_dict_access_token_payload["user_id"]
|
892
|
+
|
717
893
|
# validate user_id
|
718
894
|
local_list_user_response = global_object_square_database_helper.get_rows_v0(
|
719
895
|
database_name=global_string_database_name,
|
@@ -736,62 +912,192 @@ async def logout_v0(
|
|
736
912
|
content=output_content,
|
737
913
|
)
|
738
914
|
|
739
|
-
# validate
|
740
|
-
|
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(
|
915
|
+
# validate new username
|
916
|
+
local_list_user_credentials_response = global_object_square_database_helper.get_rows_v0(
|
744
917
|
database_name=global_string_database_name,
|
745
918
|
schema_name=global_string_schema_name,
|
746
|
-
table_name=
|
919
|
+
table_name=UserCredential.__tablename__,
|
747
920
|
filters=FiltersV0(
|
748
921
|
{
|
749
|
-
|
750
|
-
|
922
|
+
UserCredential.user_credential_username.name: FilterConditionsV0(
|
923
|
+
eq=new_username
|
924
|
+
),
|
751
925
|
}
|
752
926
|
),
|
753
|
-
)[
|
754
|
-
|
927
|
+
)[
|
928
|
+
"data"
|
929
|
+
][
|
930
|
+
"main"
|
931
|
+
]
|
932
|
+
if len(local_list_user_credentials_response) != 0:
|
755
933
|
output_content = get_api_output_in_standard_format(
|
756
|
-
message=messages["
|
757
|
-
log=f"
|
934
|
+
message=messages["USERNAME_ALREADY_EXISTS"],
|
935
|
+
log=f"{new_username} is taken.",
|
758
936
|
)
|
759
937
|
return JSONResponse(
|
760
|
-
status_code=status.
|
938
|
+
status_code=status.HTTP_409_CONFLICT,
|
939
|
+
content=output_content,
|
761
940
|
)
|
941
|
+
"""
|
942
|
+
main process
|
943
|
+
"""
|
944
|
+
# edit the username
|
945
|
+
global_object_square_database_helper.edit_rows_v0(
|
946
|
+
database_name=global_string_database_name,
|
947
|
+
schema_name=global_string_schema_name,
|
948
|
+
table_name=UserCredential.__tablename__,
|
949
|
+
filters=FiltersV0(
|
950
|
+
{
|
951
|
+
UserCredential.user_id.name: FilterConditionsV0(eq=user_id),
|
952
|
+
}
|
953
|
+
),
|
954
|
+
data={
|
955
|
+
UserCredential.user_credential_username.name: new_username,
|
956
|
+
},
|
957
|
+
)
|
958
|
+
"""
|
959
|
+
return value
|
960
|
+
"""
|
961
|
+
output_content = get_api_output_in_standard_format(
|
962
|
+
data={"main": {"user_id": user_id, "username": new_username}},
|
963
|
+
message=messages["GENERIC_UPDATE_SUCCESSFUL"],
|
964
|
+
)
|
965
|
+
return JSONResponse(status_code=status.HTTP_200_OK, content=output_content)
|
966
|
+
except HTTPException as http_exception:
|
967
|
+
return JSONResponse(
|
968
|
+
status_code=http_exception.status_code, content=http_exception.detail
|
969
|
+
)
|
970
|
+
except Exception as e:
|
971
|
+
"""
|
972
|
+
rollback logic
|
973
|
+
"""
|
974
|
+
global_object_square_logger.logger.error(e, exc_info=True)
|
975
|
+
output_content = get_api_output_in_standard_format(
|
976
|
+
message=messages["GENERIC_500"],
|
977
|
+
log=str(e),
|
978
|
+
)
|
979
|
+
return JSONResponse(
|
980
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
981
|
+
)
|
762
982
|
|
763
|
-
|
764
|
-
|
765
|
-
|
983
|
+
|
984
|
+
@router.delete("/delete_user/v0")
|
985
|
+
@global_object_square_logger.async_auto_logger
|
986
|
+
async def delete_user_v0(
|
987
|
+
body: DeleteUserV0,
|
988
|
+
access_token: Annotated[str, Header()],
|
989
|
+
):
|
990
|
+
password = body.password
|
991
|
+
try:
|
992
|
+
"""
|
993
|
+
validation
|
994
|
+
"""
|
995
|
+
# validate access token
|
996
|
+
try:
|
997
|
+
local_dict_access_token_payload = get_jwt_payload(
|
998
|
+
access_token, config_str_secret_key_for_access_token
|
999
|
+
)
|
1000
|
+
except Exception as error:
|
1001
|
+
output_content = get_api_output_in_standard_format(
|
1002
|
+
message=messages["INCORRECT_ACCESS_TOKEN"], log=str(error)
|
1003
|
+
)
|
1004
|
+
return JSONResponse(
|
1005
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
1006
|
+
content=output_content,
|
1007
|
+
)
|
1008
|
+
user_id = local_dict_access_token_payload["user_id"]
|
1009
|
+
|
1010
|
+
# validate user_id
|
1011
|
+
local_list_authentication_user_response = (
|
766
1012
|
global_object_square_database_helper.get_rows_v0(
|
767
1013
|
database_name=global_string_database_name,
|
768
1014
|
schema_name=global_string_schema_name,
|
769
|
-
table_name=
|
1015
|
+
table_name=UserCredential.__tablename__,
|
770
1016
|
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
|
-
}
|
1017
|
+
{UserCredential.user_id.name: FilterConditionsV0(eq=user_id)}
|
778
1018
|
),
|
779
1019
|
)["data"]["main"]
|
780
1020
|
)
|
1021
|
+
if len(local_list_authentication_user_response) != 1:
|
1022
|
+
output_content = get_api_output_in_standard_format(
|
1023
|
+
message=messages["INCORRECT_USER_ID"],
|
1024
|
+
log=f"incorrect user_id: {user_id}.",
|
1025
|
+
)
|
1026
|
+
return JSONResponse(
|
1027
|
+
status_code=status.HTTP_400_BAD_REQUEST, content=output_content
|
1028
|
+
)
|
781
1029
|
|
782
|
-
|
1030
|
+
# validate password
|
1031
|
+
local_dict_user = local_list_authentication_user_response[0]
|
1032
|
+
if not (
|
1033
|
+
bcrypt.checkpw(
|
1034
|
+
password.encode("utf-8"),
|
1035
|
+
local_dict_user[
|
1036
|
+
UserCredential.user_credential_hashed_password.name
|
1037
|
+
].encode("utf-8"),
|
1038
|
+
)
|
1039
|
+
):
|
783
1040
|
output_content = get_api_output_in_standard_format(
|
784
|
-
message=messages["
|
785
|
-
log=f"incorrect
|
1041
|
+
message=messages["INCORRECT_PASSWORD"],
|
1042
|
+
log=f"incorrect password for user_id {user_id}.",
|
786
1043
|
)
|
787
1044
|
return JSONResponse(
|
788
1045
|
status_code=status.HTTP_400_BAD_REQUEST,
|
789
1046
|
content=output_content,
|
790
1047
|
)
|
791
|
-
|
1048
|
+
"""
|
1049
|
+
main process
|
1050
|
+
"""
|
1051
|
+
# delete the user.
|
1052
|
+
global_object_square_database_helper.delete_rows_v0(
|
1053
|
+
database_name=global_string_database_name,
|
1054
|
+
schema_name=global_string_schema_name,
|
1055
|
+
table_name=User.__tablename__,
|
1056
|
+
filters=FiltersV0(
|
1057
|
+
{
|
1058
|
+
User.user_id.name: FilterConditionsV0(eq=user_id),
|
1059
|
+
}
|
1060
|
+
),
|
1061
|
+
)
|
1062
|
+
"""
|
1063
|
+
return value
|
1064
|
+
"""
|
1065
|
+
output_content = get_api_output_in_standard_format(
|
1066
|
+
message=messages["GENERIC_DELETE_SUCCESSFUL"],
|
1067
|
+
log=f"user_id: {user_id} deleted successfully.",
|
1068
|
+
)
|
1069
|
+
return JSONResponse(status_code=status.HTTP_200_OK, content=output_content)
|
1070
|
+
except HTTPException as http_exception:
|
1071
|
+
return JSONResponse(
|
1072
|
+
status_code=http_exception.status_code, content=http_exception.detail
|
1073
|
+
)
|
1074
|
+
except Exception as e:
|
1075
|
+
"""
|
1076
|
+
rollback logic
|
1077
|
+
"""
|
1078
|
+
global_object_square_logger.logger.error(e, exc_info=True)
|
1079
|
+
output_content = get_api_output_in_standard_format(
|
1080
|
+
message=messages["GENERIC_500"],
|
1081
|
+
log=str(e),
|
1082
|
+
)
|
1083
|
+
return JSONResponse(
|
1084
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
|
1085
|
+
)
|
1086
|
+
|
792
1087
|
|
1088
|
+
@router.patch("/update_password/v0")
|
1089
|
+
@global_object_square_logger.async_auto_logger
|
1090
|
+
async def update_password_v0(
|
1091
|
+
body: UpdatePasswordV0,
|
1092
|
+
access_token: Annotated[str, Header()],
|
1093
|
+
):
|
1094
|
+
old_password = body.old_password
|
1095
|
+
new_password = body.new_password
|
1096
|
+
try:
|
1097
|
+
"""
|
1098
|
+
validation
|
1099
|
+
"""
|
793
1100
|
# validate access token
|
794
|
-
# validating if the access token is valid, active, of the same user and of the provided app.
|
795
1101
|
try:
|
796
1102
|
local_dict_access_token_payload = get_jwt_payload(
|
797
1103
|
access_token, config_str_secret_key_for_access_token
|
@@ -804,53 +1110,72 @@ async def logout_v0(
|
|
804
1110
|
status_code=status.HTTP_400_BAD_REQUEST,
|
805
1111
|
content=output_content,
|
806
1112
|
)
|
807
|
-
|
1113
|
+
user_id = local_dict_access_token_payload["user_id"]
|
1114
|
+
|
1115
|
+
# validate user_id
|
1116
|
+
local_list_authentication_user_response = (
|
1117
|
+
global_object_square_database_helper.get_rows_v0(
|
1118
|
+
database_name=global_string_database_name,
|
1119
|
+
schema_name=global_string_schema_name,
|
1120
|
+
table_name=UserCredential.__tablename__,
|
1121
|
+
filters=FiltersV0(
|
1122
|
+
{UserCredential.user_id.name: FilterConditionsV0(eq=user_id)}
|
1123
|
+
),
|
1124
|
+
)["data"]["main"]
|
1125
|
+
)
|
1126
|
+
if len(local_list_authentication_user_response) != 1:
|
808
1127
|
output_content = get_api_output_in_standard_format(
|
809
|
-
message=messages["
|
810
|
-
log=f"
|
1128
|
+
message=messages["INCORRECT_USER_ID"],
|
1129
|
+
log=f"incorrect user_id: {user_id}.",
|
811
1130
|
)
|
812
1131
|
return JSONResponse(
|
813
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
814
|
-
content=output_content,
|
1132
|
+
status_code=status.HTTP_400_BAD_REQUEST, content=output_content
|
815
1133
|
)
|
816
|
-
|
1134
|
+
|
1135
|
+
# validate password
|
1136
|
+
local_dict_user = local_list_authentication_user_response[0]
|
1137
|
+
if not (
|
1138
|
+
bcrypt.checkpw(
|
1139
|
+
old_password.encode("utf-8"),
|
1140
|
+
local_dict_user[
|
1141
|
+
UserCredential.user_credential_hashed_password.name
|
1142
|
+
].encode("utf-8"),
|
1143
|
+
)
|
1144
|
+
):
|
817
1145
|
output_content = get_api_output_in_standard_format(
|
818
|
-
message=messages["
|
819
|
-
log=f"
|
1146
|
+
message=messages["INCORRECT_PASSWORD"],
|
1147
|
+
log=f"incorrect password for user_id {user_id}.",
|
820
1148
|
)
|
821
1149
|
return JSONResponse(
|
822
1150
|
status_code=status.HTTP_400_BAD_REQUEST,
|
823
1151
|
content=output_content,
|
824
1152
|
)
|
825
|
-
# ======================================================================================
|
826
|
-
|
827
|
-
# NOTE: if both access token and refresh token have expired for a user,
|
828
|
-
# it can be assumed that user session only needs to be removed from the front end.
|
829
|
-
|
830
|
-
# ======================================================================================
|
831
1153
|
"""
|
832
1154
|
main process
|
833
1155
|
"""
|
834
|
-
# delete
|
835
|
-
|
1156
|
+
# delete the user.
|
1157
|
+
local_str_hashed_password = bcrypt.hashpw(
|
1158
|
+
new_password.encode("utf-8"), bcrypt.gensalt()
|
1159
|
+
).decode("utf-8")
|
1160
|
+
global_object_square_database_helper.edit_rows_v0(
|
836
1161
|
database_name=global_string_database_name,
|
837
1162
|
schema_name=global_string_schema_name,
|
838
|
-
table_name=
|
1163
|
+
table_name=UserCredential.__tablename__,
|
839
1164
|
filters=FiltersV0(
|
840
1165
|
{
|
841
|
-
|
842
|
-
UserSession.user_session_refresh_token.name: FilterConditionsV0(
|
843
|
-
eq=refresh_token
|
844
|
-
),
|
845
|
-
UserSession.app_id.name: FilterConditionsV0(eq=app_id),
|
1166
|
+
UserCredential.user_id.name: FilterConditionsV0(eq=user_id),
|
846
1167
|
}
|
847
1168
|
),
|
1169
|
+
data={
|
1170
|
+
UserCredential.user_credential_hashed_password.name: local_str_hashed_password,
|
1171
|
+
},
|
848
1172
|
)
|
849
1173
|
"""
|
850
1174
|
return value
|
851
1175
|
"""
|
852
1176
|
output_content = get_api_output_in_standard_format(
|
853
|
-
message=messages["
|
1177
|
+
message=messages["GENERIC_UPDATE_SUCCESSFUL"],
|
1178
|
+
log=f"password for user_id: {user_id} updated successfully.",
|
854
1179
|
)
|
855
1180
|
return JSONResponse(status_code=status.HTTP_200_OK, content=output_content)
|
856
1181
|
except HTTPException as http_exception:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: square-authentication
|
3
|
-
Version:
|
3
|
+
Version: 4.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
|
@@ -43,6 +43,25 @@ pip install square_authentication
|
|
43
43
|
|
44
44
|
## changelog
|
45
45
|
|
46
|
+
### v4.0.0
|
47
|
+
|
48
|
+
- /login_username/v0 is now POST method.
|
49
|
+
- new flag in /login_username/v0 assign_app_id_if_missing.
|
50
|
+
- bugfix: /get_user_details/v0 now only returns number of active sessions.
|
51
|
+
|
52
|
+
### v3.0.0
|
53
|
+
|
54
|
+
- added new endpoints
|
55
|
+
- /update_username/v0
|
56
|
+
- /delete_user/v0
|
57
|
+
- /update_password/v0
|
58
|
+
- move data in password related endpoints to request body from params.
|
59
|
+
- /register_username/v0 now takes in app_id as optional parameter to assign user to that app and create session for it.
|
60
|
+
- /generate_access_token/v0 now only needs refresh token (removed validation).
|
61
|
+
- /logout/v0 now only needs refresh token (removed validation).
|
62
|
+
- /update_user_app_ids/v0 now only updates ids for self (user). added access token as input param and removed user_id.
|
63
|
+
- /get_user_app_ids/v0 is now /get_user_details/v0 with access token as the only input param.
|
64
|
+
|
46
65
|
### v2.0.0
|
47
66
|
|
48
67
|
- authentication module needs to be used across applications so
|
@@ -1,15 +1,17 @@
|
|
1
1
|
square_authentication/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
2
|
square_authentication/configuration.py,sha256=i0uNtNSQd-n1rBxFM6jsIz1Wy3d090RcdTViSqHKc7Y,2973
|
3
3
|
square_authentication/main.py,sha256=JK9KBmN73KL8EpKrXrjrwwf37bmC4AXrFHtfl2roYwQ,1636
|
4
|
-
square_authentication/messages.py,sha256=
|
4
|
+
square_authentication/messages.py,sha256=BA9KC0vW9UD1ZXT4VneVqVNLlgdbMdsAwAgxhJISLf4,1175
|
5
5
|
square_authentication/data/config.ini,sha256=_740RvKpL5W2bUDGwZ7ePwuP-mAasr5cXXB81yq_Jv8,906
|
6
|
+
square_authentication/pydantic_models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
7
|
+
square_authentication/pydantic_models/core.py,sha256=Hwzr-YJH6GVGLp4Z29iHItOEhiEvk65MjsttmCaDTe4,431
|
6
8
|
square_authentication/routes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
7
|
-
square_authentication/routes/core.py,sha256=
|
9
|
+
square_authentication/routes/core.py,sha256=o9FeIGMdQbkBLZ0d9GdyEOJJkRMBsYRyUKOO9l5vWgA,44551
|
8
10
|
square_authentication/routes/utility.py,sha256=Kx4S4tZ1GKsPoC8CoZ4fkLEebvr02KeFEPePtTHtpnQ,75
|
9
11
|
square_authentication/utils/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
10
12
|
square_authentication/utils/encryption.py,sha256=T6BShoUr_xeGpbfPgTK-GxTlXPwcjwU4c4KW7KPzrF8,1865
|
11
13
|
square_authentication/utils/token.py,sha256=Y_arg5LegX-aprMj9YweUK8jjNZLGDjLUGgxbUA12w4,560
|
12
|
-
square_authentication-
|
13
|
-
square_authentication-
|
14
|
-
square_authentication-
|
15
|
-
square_authentication-
|
14
|
+
square_authentication-4.0.0.dist-info/METADATA,sha256=spjL_EnrXbwC-em5JgyrzlCq0HD0QHDzXEagx9DzLHM,2810
|
15
|
+
square_authentication-4.0.0.dist-info/WHEEL,sha256=bFJAMchF8aTQGUgMZzHJyDDMPTO3ToJ7x23SLJa1SVo,92
|
16
|
+
square_authentication-4.0.0.dist-info/top_level.txt,sha256=wDssVJIl9KIEJPj5rR3rv4uRI7yCndMBrvHd_6BGXQA,22
|
17
|
+
square_authentication-4.0.0.dist-info/RECORD,,
|
{square_authentication-2.0.0.dist-info → square_authentication-4.0.0.dist-info}/top_level.txt
RENAMED
File without changes
|