square-authentication 6.1.0__tar.gz → 6.2.1__tar.gz

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.
Files changed (26) hide show
  1. {square_authentication-6.1.0 → square_authentication-6.2.1}/PKG-INFO +11 -1
  2. {square_authentication-6.1.0 → square_authentication-6.2.1}/README.md +10 -0
  3. {square_authentication-6.1.0 → square_authentication-6.2.1}/setup.py +1 -1
  4. {square_authentication-6.1.0 → square_authentication-6.2.1}/square_authentication/routes/core.py +150 -10
  5. {square_authentication-6.1.0 → square_authentication-6.2.1}/square_authentication.egg-info/PKG-INFO +11 -1
  6. {square_authentication-6.1.0 → square_authentication-6.2.1}/tests/test_username.py +7 -7
  7. {square_authentication-6.1.0 → square_authentication-6.2.1}/setup.cfg +0 -0
  8. {square_authentication-6.1.0 → square_authentication-6.2.1}/square_authentication/__init__.py +0 -0
  9. {square_authentication-6.1.0 → square_authentication-6.2.1}/square_authentication/configuration.py +0 -0
  10. {square_authentication-6.1.0 → square_authentication-6.2.1}/square_authentication/data/config.ini +0 -0
  11. {square_authentication-6.1.0 → square_authentication-6.2.1}/square_authentication/data/config.testing.ini +0 -0
  12. {square_authentication-6.1.0 → square_authentication-6.2.1}/square_authentication/main.py +0 -0
  13. {square_authentication-6.1.0 → square_authentication-6.2.1}/square_authentication/messages.py +0 -0
  14. {square_authentication-6.1.0 → square_authentication-6.2.1}/square_authentication/pydantic_models/__init__.py +0 -0
  15. {square_authentication-6.1.0 → square_authentication-6.2.1}/square_authentication/pydantic_models/core.py +0 -0
  16. {square_authentication-6.1.0 → square_authentication-6.2.1}/square_authentication/routes/__init__.py +0 -0
  17. {square_authentication-6.1.0 → square_authentication-6.2.1}/square_authentication/routes/profile.py +0 -0
  18. {square_authentication-6.1.0 → square_authentication-6.2.1}/square_authentication/routes/utility.py +0 -0
  19. {square_authentication-6.1.0 → square_authentication-6.2.1}/square_authentication/utils/__init__.py +0 -0
  20. {square_authentication-6.1.0 → square_authentication-6.2.1}/square_authentication/utils/encryption.py +0 -0
  21. {square_authentication-6.1.0 → square_authentication-6.2.1}/square_authentication/utils/token.py +0 -0
  22. {square_authentication-6.1.0 → square_authentication-6.2.1}/square_authentication.egg-info/SOURCES.txt +0 -0
  23. {square_authentication-6.1.0 → square_authentication-6.2.1}/square_authentication.egg-info/dependency_links.txt +0 -0
  24. {square_authentication-6.1.0 → square_authentication-6.2.1}/square_authentication.egg-info/requires.txt +0 -0
  25. {square_authentication-6.1.0 → square_authentication-6.2.1}/square_authentication.egg-info/top_level.txt +0 -0
  26. {square_authentication-6.1.0 → square_authentication-6.2.1}/tests/test_1.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: square_authentication
3
- Version: 6.1.0
3
+ Version: 6.2.1
4
4
  Summary: authentication layer for my personal server.
5
5
  Home-page: https://github.com/thepmsquare/square_authentication
6
6
  Author: thePmSquare
@@ -53,6 +53,16 @@ pip install square_authentication
53
53
 
54
54
  ## changelog
55
55
 
56
+ ### v6.2.1
57
+
58
+ - core
59
+ - tweak validation for username in register_username_v0 and update_username_v0.
60
+
61
+ ### v6.2.0
62
+
63
+ - core
64
+ - add update_user_recovery_methods_v0.
65
+
56
66
  ### v6.1.0
57
67
 
58
68
  - add validation to username in register_username_v0 and update_username_v0.
@@ -16,6 +16,16 @@ pip install square_authentication
16
16
 
17
17
  ## changelog
18
18
 
19
+ ### v6.2.1
20
+
21
+ - core
22
+ - tweak validation for username in register_username_v0 and update_username_v0.
23
+
24
+ ### v6.2.0
25
+
26
+ - core
27
+ - add update_user_recovery_methods_v0.
28
+
19
29
  ### v6.1.0
20
30
 
21
31
  - add validation to username in register_username_v0 and update_username_v0.
@@ -4,7 +4,7 @@ package_name = "square_authentication"
4
4
 
5
5
  setup(
6
6
  name=package_name,
7
- version="6.1.0",
7
+ version="6.2.1",
8
8
  packages=find_packages(),
9
9
  package_data={
10
10
  package_name: ["data/*"],
@@ -13,12 +13,14 @@ from square_commons import get_api_output_in_standard_format
13
13
  from square_database_helper.pydantic_models import FilterConditionsV0, FiltersV0
14
14
  from square_database_structure.square import global_string_database_name
15
15
  from square_database_structure.square.authentication import global_string_schema_name
16
+ from square_database_structure.square.authentication.enums import RecoveryMethodEnum
16
17
  from square_database_structure.square.authentication.tables import (
17
18
  User,
18
19
  UserApp,
19
20
  UserCredential,
20
21
  UserSession,
21
22
  UserProfile,
23
+ UserRecoveryMethod,
22
24
  )
23
25
  from square_database_structure.square.public import (
24
26
  global_string_schema_name as global_string_public_schema_name,
@@ -68,11 +70,7 @@ async def register_username_v0(
68
70
  validation
69
71
  """
70
72
  # validation for username
71
- # ^(?!.*[_-]{2}) # no consecutive _ or -
72
- # [a-z] # must start with a lowercase letter
73
- # (?:[a-z0-9_-]{1,18}) # 1–18 of lowercase, digits, _ or -
74
- # [a-z]$ # must end with a lowercase letter
75
- username_pattern = re.compile(r"^(?!.*[._-]{2})[a-z][a-z0-9_-]{1,18}[a-z]$")
73
+ username_pattern = re.compile(r"^[a-z0-9._-]{2,20}$")
76
74
  if not username_pattern.match(username):
77
75
  output_content = get_api_output_in_standard_format(
78
76
  message=messages["USERNAME_INVALID"],
@@ -1116,12 +1114,8 @@ async def update_username_v0(
1116
1114
  user_id = local_dict_access_token_payload["user_id"]
1117
1115
 
1118
1116
  # validation for username
1119
- # ^(?!.*[_-]{2}) # no consecutive _ or -
1120
- # [a-z] # must start with a lowercase letter
1121
- # (?:[a-z0-9_-]{1,18}) # 1–18 of lowercase, digits, _ or -
1122
- # [a-z]$ # must end with a lowercase letter
1123
1117
  new_username = new_username.lower()
1124
- username_pattern = re.compile(r"^(?!.*[._-]{2})[a-z][a-z0-9_-]{1,18}[a-z]$")
1118
+ username_pattern = re.compile(r"^[a-z0-9._-]{2,20}$")
1125
1119
  if not username_pattern.match(new_username):
1126
1120
  output_content = get_api_output_in_standard_format(
1127
1121
  message=messages["USERNAME_INVALID"],
@@ -1540,3 +1534,149 @@ async def validate_and_get_payload_from_token_v0(
1540
1534
  return JSONResponse(
1541
1535
  status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=output_content
1542
1536
  )
1537
+
1538
+
1539
+ @router.patch("/update_user_recovery_methods/v0")
1540
+ @global_object_square_logger.auto_logger()
1541
+ async def update_user_recovery_methods_v0(
1542
+ access_token: Annotated[str, Header()],
1543
+ recovery_methods_to_add: List[RecoveryMethodEnum],
1544
+ recovery_methods_to_remove: List[RecoveryMethodEnum],
1545
+ ):
1546
+ try:
1547
+
1548
+ """
1549
+ validation
1550
+ """
1551
+ # validate access token
1552
+ try:
1553
+ local_dict_access_token_payload = get_jwt_payload(
1554
+ access_token, config_str_secret_key_for_access_token
1555
+ )
1556
+ except Exception as error:
1557
+ output_content = get_api_output_in_standard_format(
1558
+ message=messages["INCORRECT_ACCESS_TOKEN"], log=str(error)
1559
+ )
1560
+ raise HTTPException(
1561
+ status_code=status.HTTP_400_BAD_REQUEST,
1562
+ detail=output_content,
1563
+ )
1564
+ user_id = local_dict_access_token_payload["user_id"]
1565
+
1566
+ recovery_methods_to_add = list(set(x.value for x in recovery_methods_to_add))
1567
+ recovery_methods_to_remove = list(
1568
+ set(x.value for x in recovery_methods_to_remove)
1569
+ )
1570
+
1571
+ # check if recovery_methods_to_add and recovery_methods_to_remove don't have common ids.
1572
+ local_list_common_recovery_methods = set(recovery_methods_to_add) & set(
1573
+ recovery_methods_to_remove
1574
+ )
1575
+ if len(local_list_common_recovery_methods) > 0:
1576
+ output_content = get_api_output_in_standard_format(
1577
+ message=messages["GENERIC_400"],
1578
+ log=f"invalid recovery_methods: {list(local_list_common_recovery_methods)}, present in both add list and remove list.",
1579
+ )
1580
+ raise HTTPException(
1581
+ status_code=status.HTTP_400_BAD_REQUEST,
1582
+ detail=output_content,
1583
+ )
1584
+
1585
+ """
1586
+ main process
1587
+ """
1588
+ # logic for adding new recovery_methods
1589
+ local_list_response_user_recovery_methods = (
1590
+ global_object_square_database_helper.get_rows_v0(
1591
+ database_name=global_string_database_name,
1592
+ schema_name=global_string_schema_name,
1593
+ table_name=UserRecoveryMethod.__tablename__,
1594
+ filters=FiltersV0(
1595
+ root={
1596
+ UserRecoveryMethod.user_id.name: FilterConditionsV0(eq=user_id)
1597
+ }
1598
+ ),
1599
+ )["data"]["main"]
1600
+ )
1601
+ local_list_new_recovery_methods = [
1602
+ {
1603
+ UserRecoveryMethod.user_id.name: user_id,
1604
+ UserRecoveryMethod.user_recovery_method_name.name: x,
1605
+ }
1606
+ for x in recovery_methods_to_add
1607
+ if x
1608
+ not in [
1609
+ y[UserRecoveryMethod.user_recovery_method_name.name]
1610
+ for y in local_list_response_user_recovery_methods
1611
+ ]
1612
+ ]
1613
+ if len(local_list_new_recovery_methods) > 0:
1614
+ global_object_square_database_helper.insert_rows_v0(
1615
+ database_name=global_string_database_name,
1616
+ schema_name=global_string_schema_name,
1617
+ table_name=UserRecoveryMethod.__tablename__,
1618
+ data=local_list_new_recovery_methods,
1619
+ )
1620
+
1621
+ # logic for removing recovery_methods
1622
+ global_object_square_database_helper.delete_rows_v0(
1623
+ database_name=global_string_database_name,
1624
+ schema_name=global_string_schema_name,
1625
+ table_name=UserRecoveryMethod.__tablename__,
1626
+ filters=FiltersV0(
1627
+ root={
1628
+ UserRecoveryMethod.user_id.name: FilterConditionsV0(eq=user_id),
1629
+ UserRecoveryMethod.user_recovery_method_name.name: FilterConditionsV0(
1630
+ in_=recovery_methods_to_remove
1631
+ ),
1632
+ }
1633
+ ),
1634
+ )
1635
+
1636
+ """
1637
+ return value
1638
+ """
1639
+ # get latest recovery_methods
1640
+ local_list_response_user_recovery_methods = (
1641
+ global_object_square_database_helper.get_rows_v0(
1642
+ database_name=global_string_database_name,
1643
+ schema_name=global_string_schema_name,
1644
+ table_name=UserRecoveryMethod.__tablename__,
1645
+ filters=FiltersV0(
1646
+ root={
1647
+ UserRecoveryMethod.user_id.name: FilterConditionsV0(eq=user_id)
1648
+ }
1649
+ ),
1650
+ )["data"]["main"]
1651
+ )
1652
+ output_content = get_api_output_in_standard_format(
1653
+ message=messages["GENERIC_UPDATE_SUCCESSFUL"],
1654
+ data={
1655
+ "main": [
1656
+ x[UserRecoveryMethod.user_recovery_method_name.name]
1657
+ for x in local_list_response_user_recovery_methods
1658
+ ]
1659
+ },
1660
+ )
1661
+ return JSONResponse(
1662
+ status_code=status.HTTP_200_OK,
1663
+ content=output_content,
1664
+ )
1665
+ except HTTPException as http_exception:
1666
+ global_object_square_logger.logger.error(http_exception, exc_info=True)
1667
+ return JSONResponse(
1668
+ status_code=http_exception.status_code, content=http_exception.detail
1669
+ )
1670
+ except Exception as e:
1671
+ """
1672
+ rollback logic
1673
+ """
1674
+ global_object_square_logger.logger.error(e, exc_info=True)
1675
+ output_content = get_api_output_in_standard_format(
1676
+ message=messages["GENERIC_500"],
1677
+ log=str(e),
1678
+ )
1679
+ return JSONResponse(
1680
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
1681
+ content=output_content,
1682
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: square_authentication
3
- Version: 6.1.0
3
+ Version: 6.2.1
4
4
  Summary: authentication layer for my personal server.
5
5
  Home-page: https://github.com/thepmsquare/square_authentication
6
6
  Author: thePmSquare
@@ -53,6 +53,16 @@ pip install square_authentication
53
53
 
54
54
  ## changelog
55
55
 
56
+ ### v6.2.1
57
+
58
+ - core
59
+ - tweak validation for username in register_username_v0 and update_username_v0.
60
+
61
+ ### v6.2.0
62
+
63
+ - core
64
+ - add update_user_recovery_methods_v0.
65
+
56
66
  ### v6.1.0
57
67
 
58
68
  - add validation to username in register_username_v0 and update_username_v0.
@@ -1,15 +1,15 @@
1
1
  from square_authentication.messages import messages
2
2
 
3
3
 
4
- def test_register_username_invalid(create_client_and_cleanup):
4
+ def test_register_username_consecutive_special_chars(create_client_and_cleanup):
5
5
  payload = {
6
6
  "username": "invalid..name",
7
7
  "password": "testpass123",
8
8
  "app_id": 1,
9
9
  }
10
10
  response = create_client_and_cleanup.post("/register_username/v0", json=payload)
11
- assert response.status_code == 400
12
- assert "username" in response.json()["log"]
11
+ assert response.status_code == 201
12
+ assert response.json()["message"] == messages["REGISTRATION_SUCCESSFUL"]
13
13
 
14
14
 
15
15
  def test_username_starts_with_number(create_client_and_cleanup):
@@ -19,8 +19,8 @@ def test_username_starts_with_number(create_client_and_cleanup):
19
19
  "app_id": 1,
20
20
  }
21
21
  response = create_client_and_cleanup.post("/register_username/v0", json=payload)
22
- assert response.status_code == 400
23
- assert "username" in response.json()["log"]
22
+ assert response.status_code == 201
23
+ assert response.json()["message"] == messages["REGISTRATION_SUCCESSFUL"]
24
24
 
25
25
 
26
26
  def test_username_ends_with_number(create_client_and_cleanup):
@@ -30,8 +30,8 @@ def test_username_ends_with_number(create_client_and_cleanup):
30
30
  "app_id": 1,
31
31
  }
32
32
  response = create_client_and_cleanup.post("/register_username/v0", json=payload)
33
- assert response.status_code == 400
34
- assert "username" in response.json()["log"]
33
+ assert response.status_code == 201
34
+ assert response.json()["message"] == messages["REGISTRATION_SUCCESSFUL"]
35
35
 
36
36
 
37
37
  def test_username_with_space(create_client_and_cleanup):