square-authentication 8.0.2__tar.gz → 9.0.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 (32) hide show
  1. {square_authentication-8.0.2 → square_authentication-9.0.1}/PKG-INFO +18 -1
  2. {square_authentication-8.0.2 → square_authentication-9.0.1}/README.md +17 -0
  3. {square_authentication-8.0.2 → square_authentication-9.0.1}/setup.py +1 -1
  4. {square_authentication-8.0.2 → square_authentication-9.0.1}/square_authentication/configuration.py +11 -1
  5. {square_authentication-8.0.2 → square_authentication-9.0.1}/square_authentication/data/config.sample.ini +3 -1
  6. {square_authentication-8.0.2 → square_authentication-9.0.1}/square_authentication/data/config.testing.sample.ini +3 -1
  7. {square_authentication-8.0.2 → square_authentication-9.0.1}/square_authentication/routes/core.py +66 -1
  8. {square_authentication-8.0.2 → square_authentication-9.0.1}/square_authentication/routes/profile.py +52 -0
  9. {square_authentication-8.0.2 → square_authentication-9.0.1}/square_authentication.egg-info/PKG-INFO +18 -1
  10. {square_authentication-8.0.2 → square_authentication-9.0.1}/pyproject.toml +0 -0
  11. {square_authentication-8.0.2 → square_authentication-9.0.1}/setup.cfg +0 -0
  12. {square_authentication-8.0.2 → square_authentication-9.0.1}/square_authentication/__init__.py +0 -0
  13. {square_authentication-8.0.2 → square_authentication-9.0.1}/square_authentication/main.py +0 -0
  14. {square_authentication-8.0.2 → square_authentication-9.0.1}/square_authentication/messages.py +0 -0
  15. {square_authentication-8.0.2 → square_authentication-9.0.1}/square_authentication/pydantic_models/__init__.py +0 -0
  16. {square_authentication-8.0.2 → square_authentication-9.0.1}/square_authentication/pydantic_models/core.py +0 -0
  17. {square_authentication-8.0.2 → square_authentication-9.0.1}/square_authentication/pydantic_models/profile.py +0 -0
  18. {square_authentication-8.0.2 → square_authentication-9.0.1}/square_authentication/routes/__init__.py +0 -0
  19. {square_authentication-8.0.2 → square_authentication-9.0.1}/square_authentication/routes/utility.py +0 -0
  20. {square_authentication-8.0.2 → square_authentication-9.0.1}/square_authentication/utils/__init__.py +0 -0
  21. {square_authentication-8.0.2 → square_authentication-9.0.1}/square_authentication/utils/core.py +0 -0
  22. {square_authentication-8.0.2 → square_authentication-9.0.1}/square_authentication/utils/encryption.py +0 -0
  23. {square_authentication-8.0.2 → square_authentication-9.0.1}/square_authentication/utils/token.py +0 -0
  24. {square_authentication-8.0.2 → square_authentication-9.0.1}/square_authentication.egg-info/SOURCES.txt +0 -0
  25. {square_authentication-8.0.2 → square_authentication-9.0.1}/square_authentication.egg-info/dependency_links.txt +0 -0
  26. {square_authentication-8.0.2 → square_authentication-9.0.1}/square_authentication.egg-info/requires.txt +0 -0
  27. {square_authentication-8.0.2 → square_authentication-9.0.1}/square_authentication.egg-info/top_level.txt +0 -0
  28. {square_authentication-8.0.2 → square_authentication-9.0.1}/tests/test_1.py +0 -0
  29. {square_authentication-8.0.2 → square_authentication-9.0.1}/tests/test_delete_user.py +0 -0
  30. {square_authentication-8.0.2 → square_authentication-9.0.1}/tests/test_login.py +0 -0
  31. {square_authentication-8.0.2 → square_authentication-9.0.1}/tests/test_update_profile.py +0 -0
  32. {square_authentication-8.0.2 → square_authentication-9.0.1}/tests/test_username.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: square_authentication
3
- Version: 8.0.2
3
+ Version: 9.0.1
4
4
  Summary: authentication layer for my personal server.
5
5
  Home-page: https://github.com/thepmsquare/square_authentication
6
6
  Author: thePmSquare
@@ -54,6 +54,23 @@ pip install square_authentication
54
54
 
55
55
  ## changelog
56
56
 
57
+ ### v9.0.1
58
+
59
+ - env
60
+ - add RESEND_COOL_DOWN_TIME_FOR_EMAIL_VERIFICATION_CODE_IN_SECONDS and
61
+ RESEND_COOL_DOWN_TIME_FOR_EMAIL_PASSWORD_RESET_CODE_IN_SECONDS in LOGIC section.
62
+ - profile
63
+ - add validation for email verification code already sent in send_verification_email_v0.
64
+ - add cooldown_reset_at in send_verification_email_v0 output.
65
+ - core
66
+ - add validation for email password reset code already sent in send_reset_password_email_v0.
67
+ - add cooldown_reset_at in send_reset_password_email_v0 output.
68
+
69
+ ### v9.0.0
70
+
71
+ - core
72
+ - **breaking change**: new mandatory parameter `app_id` in validate_and_get_payload_from_token_v0.
73
+
57
74
  ### v8.0.2
58
75
 
59
76
  - core
@@ -16,6 +16,23 @@ pip install square_authentication
16
16
 
17
17
  ## changelog
18
18
 
19
+ ### v9.0.1
20
+
21
+ - env
22
+ - add RESEND_COOL_DOWN_TIME_FOR_EMAIL_VERIFICATION_CODE_IN_SECONDS and
23
+ RESEND_COOL_DOWN_TIME_FOR_EMAIL_PASSWORD_RESET_CODE_IN_SECONDS in LOGIC section.
24
+ - profile
25
+ - add validation for email verification code already sent in send_verification_email_v0.
26
+ - add cooldown_reset_at in send_verification_email_v0 output.
27
+ - core
28
+ - add validation for email password reset code already sent in send_reset_password_email_v0.
29
+ - add cooldown_reset_at in send_reset_password_email_v0 output.
30
+
31
+ ### v9.0.0
32
+
33
+ - core
34
+ - **breaking change**: new mandatory parameter `app_id` in validate_and_get_payload_from_token_v0.
35
+
19
36
  ### v8.0.2
20
37
 
21
38
  - core
@@ -4,7 +4,7 @@ package_name = "square_authentication"
4
4
 
5
5
  setup(
6
6
  name=package_name,
7
- version="8.0.2",
7
+ version="9.0.1",
8
8
  packages=find_packages(),
9
9
  package_data={
10
10
  package_name: ["data/*"],
@@ -108,7 +108,7 @@ try:
108
108
  ]
109
109
  # ===========================================
110
110
  # ===========================================
111
- # GOOGLE
111
+ # LOGIC
112
112
 
113
113
  NUMBER_OF_RECOVERY_CODES = int(
114
114
  ldict_configuration["LOGIC"]["NUMBER_OF_RECOVERY_CODES"]
@@ -129,6 +129,16 @@ try:
129
129
  NUMBER_OF_DIGITS_IN_EMAIL_PASSWORD_RESET_CODE = int(
130
130
  ldict_configuration["LOGIC"]["NUMBER_OF_DIGITS_IN_EMAIL_PASSWORD_RESET_CODE"]
131
131
  )
132
+ RESEND_COOL_DOWN_TIME_FOR_EMAIL_VERIFICATION_CODE_IN_SECONDS = int(
133
+ ldict_configuration["LOGIC"][
134
+ "RESEND_COOL_DOWN_TIME_FOR_EMAIL_VERIFICATION_CODE_IN_SECONDS"
135
+ ]
136
+ )
137
+ RESEND_COOL_DOWN_TIME_FOR_EMAIL_PASSWORD_RESET_CODE_IN_SECONDS = int(
138
+ ldict_configuration["LOGIC"][
139
+ "RESEND_COOL_DOWN_TIME_FOR_EMAIL_PASSWORD_RESET_CODE_IN_SECONDS"
140
+ ]
141
+ )
132
142
  # ===========================================
133
143
 
134
144
  # Initialize logger
@@ -64,4 +64,6 @@ NUMBER_OF_RECOVERY_CODES = 10
64
64
  EXPIRY_TIME_FOR_EMAIL_VERIFICATION_CODE_IN_SECONDS = 600
65
65
  NUMBER_OF_DIGITS_IN_EMAIL_VERIFICATION_CODE = 6
66
66
  EXPIRY_TIME_FOR_EMAIL_PASSWORD_RESET_CODE_IN_SECONDS = 600
67
- NUMBER_OF_DIGITS_IN_EMAIL_PASSWORD_RESET_CODE = 6
67
+ NUMBER_OF_DIGITS_IN_EMAIL_PASSWORD_RESET_CODE = 6
68
+ RESEND_COOL_DOWN_TIME_FOR_EMAIL_VERIFICATION_CODE_IN_SECONDS = 60
69
+ RESEND_COOL_DOWN_TIME_FOR_EMAIL_PASSWORD_RESET_CODE_IN_SECONDS = 60
@@ -64,4 +64,6 @@ NUMBER_OF_RECOVERY_CODES = 10
64
64
  EXPIRY_TIME_FOR_EMAIL_VERIFICATION_CODE_IN_SECONDS = 600
65
65
  NUMBER_OF_DIGITS_IN_EMAIL_VERIFICATION_CODE = 6
66
66
  EXPIRY_TIME_FOR_EMAIL_PASSWORD_RESET_CODE_IN_SECONDS = 600
67
- NUMBER_OF_DIGITS_IN_EMAIL_PASSWORD_RESET_CODE = 6
67
+ NUMBER_OF_DIGITS_IN_EMAIL_PASSWORD_RESET_CODE = 6
68
+ RESEND_COOL_DOWN_TIME_FOR_EMAIL_VERIFICATION_CODE_IN_SECONDS = 60
69
+ RESEND_COOL_DOWN_TIME_FOR_EMAIL_PASSWORD_RESET_CODE_IN_SECONDS = 60
@@ -58,6 +58,7 @@ from square_authentication.configuration import (
58
58
  NUMBER_OF_DIGITS_IN_EMAIL_PASSWORD_RESET_CODE,
59
59
  EXPIRY_TIME_FOR_EMAIL_PASSWORD_RESET_CODE_IN_SECONDS,
60
60
  global_object_square_file_store_helper,
61
+ RESEND_COOL_DOWN_TIME_FOR_EMAIL_PASSWORD_RESET_CODE_IN_SECONDS,
61
62
  )
62
63
  from square_authentication.messages import messages
63
64
  from square_authentication.pydantic_models.core import (
@@ -1975,6 +1976,7 @@ async def update_password_v0(
1975
1976
  @router.get("/validate_and_get_payload_from_token/v0")
1976
1977
  @global_object_square_logger.auto_logger()
1977
1978
  async def validate_and_get_payload_from_token_v0(
1979
+ app_id: int,
1978
1980
  token: Annotated[str, Header()],
1979
1981
  token_type: TokenType = Query(...),
1980
1982
  ):
@@ -2022,6 +2024,15 @@ async def validate_and_get_payload_from_token_v0(
2022
2024
  status_code=status.HTTP_400_BAD_REQUEST,
2023
2025
  detail=output_content,
2024
2026
  )
2027
+ if local_dict_token_payload["app_id"] != app_id:
2028
+ output_content = get_api_output_in_standard_format(
2029
+ message=messages["GENERIC_400"],
2030
+ log=f"app_id: {app_id} does not match with token app_id: {local_dict_token_payload['app_id']}.",
2031
+ )
2032
+ raise HTTPException(
2033
+ status_code=status.HTTP_400_BAD_REQUEST,
2034
+ detail=output_content,
2035
+ )
2025
2036
  except HTTPException as http_exception:
2026
2037
  raise
2027
2038
  except Exception as error:
@@ -2830,7 +2841,57 @@ async def send_reset_password_email_v0(
2830
2841
  log="email is not verified.",
2831
2842
  )
2832
2843
  return JSONResponse(status_code=status.HTTP_200_OK, content=output_content)
2833
-
2844
+ # check if reset password code already exists
2845
+ local_list_response_user_verification_code = global_object_square_database_helper.get_rows_v0(
2846
+ database_name=global_string_database_name,
2847
+ schema_name=global_string_schema_name,
2848
+ table_name=UserVerificationCode.__tablename__,
2849
+ filters=FiltersV0(
2850
+ root={
2851
+ UserVerificationCode.user_id.name: FilterConditionsV0(eq=user_id),
2852
+ UserVerificationCode.user_verification_code_type.name: FilterConditionsV0(
2853
+ eq=VerificationCodeTypeEnum.EMAIL_RECOVERY.value
2854
+ ),
2855
+ UserVerificationCode.user_verification_code_used_at.name: FilterConditionsV0(
2856
+ is_null=True
2857
+ ),
2858
+ UserVerificationCode.user_verification_code_expires_at.name: FilterConditionsV0(
2859
+ gte=datetime.now(timezone.utc).strftime(
2860
+ "%Y-%m-%d %H:%M:%S.%f+00"
2861
+ )
2862
+ ),
2863
+ }
2864
+ ),
2865
+ order_by=[
2866
+ "-" + UserVerificationCode.user_verification_code_created_at.name
2867
+ ],
2868
+ limit=1,
2869
+ apply_filters=True,
2870
+ )[
2871
+ "data"
2872
+ ][
2873
+ "main"
2874
+ ]
2875
+ if len(local_list_response_user_verification_code) > 0:
2876
+ existing_verification_code_data = (
2877
+ local_list_response_user_verification_code[0]
2878
+ )
2879
+ if (
2880
+ datetime.now(timezone.utc)
2881
+ - datetime.fromisoformat(
2882
+ existing_verification_code_data[
2883
+ UserVerificationCode.user_verification_code_created_at.name
2884
+ ]
2885
+ )
2886
+ ).total_seconds() < RESEND_COOL_DOWN_TIME_FOR_EMAIL_PASSWORD_RESET_CODE_IN_SECONDS:
2887
+ output_content = get_api_output_in_standard_format(
2888
+ message=messages["GENERIC_400"],
2889
+ log="verification code already exists and was sent within the cooldown period.",
2890
+ )
2891
+ raise HTTPException(
2892
+ status_code=status.HTTP_400_BAD_REQUEST,
2893
+ detail=output_content,
2894
+ )
2834
2895
  """
2835
2896
  main process
2836
2897
  """
@@ -2904,9 +2965,13 @@ async def send_reset_password_email_v0(
2904
2965
  """
2905
2966
  return value
2906
2967
  """
2968
+ cooldown_reset_at = datetime.now(timezone.utc) + timedelta(
2969
+ seconds=EXPIRY_TIME_FOR_EMAIL_PASSWORD_RESET_CODE_IN_SECONDS,
2970
+ )
2907
2971
  output_content = get_api_output_in_standard_format(
2908
2972
  data={
2909
2973
  "expires_at": expires_at.isoformat(),
2974
+ "cooldown_reset_at": cooldown_reset_at.isoformat(),
2910
2975
  },
2911
2976
  message=messages["GENERIC_ACTION_SUCCESSFUL"],
2912
2977
  )
@@ -32,6 +32,7 @@ from square_authentication.configuration import (
32
32
  MAIL_GUN_API_KEY,
33
33
  NUMBER_OF_DIGITS_IN_EMAIL_VERIFICATION_CODE,
34
34
  EXPIRY_TIME_FOR_EMAIL_VERIFICATION_CODE_IN_SECONDS,
35
+ RESEND_COOL_DOWN_TIME_FOR_EMAIL_VERIFICATION_CODE_IN_SECONDS,
35
36
  )
36
37
  from square_authentication.messages import messages
37
38
  from square_authentication.pydantic_models.profile import (
@@ -357,6 +358,53 @@ async def send_verification_email_v0(
357
358
  message=messages["EMAIL_ALREADY_VERIFIED"]
358
359
  )
359
360
  return JSONResponse(status_code=status.HTTP_200_OK, content=output_content)
361
+ # check if email verification code already exists
362
+ existing_verification_code_response = global_object_square_database_helper.get_rows_v0(
363
+ database_name=global_string_database_name,
364
+ schema_name=global_string_schema_name,
365
+ table_name=UserVerificationCode.__tablename__,
366
+ filters=FiltersV0(
367
+ root={
368
+ UserVerificationCode.user_id.name: FilterConditionsV0(eq=user_id),
369
+ UserVerificationCode.user_verification_code_type.name: FilterConditionsV0(
370
+ eq=VerificationCodeTypeEnum.EMAIL_VERIFICATION.value
371
+ ),
372
+ UserVerificationCode.user_verification_code_used_at.name: FilterConditionsV0(
373
+ is_null=True
374
+ ),
375
+ UserVerificationCode.user_verification_code_expires_at.name: FilterConditionsV0(
376
+ gte=datetime.now(timezone.utc).strftime(
377
+ "%Y-%m-%d %H:%M:%S.%f+00"
378
+ )
379
+ ),
380
+ }
381
+ ),
382
+ order_by=[
383
+ "-" + UserVerificationCode.user_verification_code_created_at.name
384
+ ],
385
+ limit=1,
386
+ apply_filters=True,
387
+ )
388
+ if len(existing_verification_code_response["data"]["main"]) > 0:
389
+ existing_verification_code_data = existing_verification_code_response[
390
+ "data"
391
+ ]["main"][0]
392
+ if (
393
+ datetime.now(timezone.utc)
394
+ - datetime.fromisoformat(
395
+ existing_verification_code_data[
396
+ UserVerificationCode.user_verification_code_created_at.name
397
+ ]
398
+ )
399
+ ).total_seconds() < RESEND_COOL_DOWN_TIME_FOR_EMAIL_VERIFICATION_CODE_IN_SECONDS:
400
+ output_content = get_api_output_in_standard_format(
401
+ message=messages["GENERIC_400"],
402
+ log="verification code already exists and was sent within the cooldown period.",
403
+ )
404
+ raise HTTPException(
405
+ status_code=status.HTTP_400_BAD_REQUEST,
406
+ detail=output_content,
407
+ )
360
408
 
361
409
  """
362
410
  main process
@@ -431,9 +479,13 @@ async def send_verification_email_v0(
431
479
  """
432
480
  return value
433
481
  """
482
+ cooldown_reset_at = datetime.now(timezone.utc) + timedelta(
483
+ seconds=RESEND_COOL_DOWN_TIME_FOR_EMAIL_VERIFICATION_CODE_IN_SECONDS
484
+ )
434
485
  output_content = get_api_output_in_standard_format(
435
486
  data={
436
487
  "expires_at": expires_at.isoformat(),
488
+ "cooldown_reset_at": cooldown_reset_at.isoformat(),
437
489
  },
438
490
  message=messages["GENERIC_ACTION_SUCCESSFUL"],
439
491
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: square_authentication
3
- Version: 8.0.2
3
+ Version: 9.0.1
4
4
  Summary: authentication layer for my personal server.
5
5
  Home-page: https://github.com/thepmsquare/square_authentication
6
6
  Author: thePmSquare
@@ -54,6 +54,23 @@ pip install square_authentication
54
54
 
55
55
  ## changelog
56
56
 
57
+ ### v9.0.1
58
+
59
+ - env
60
+ - add RESEND_COOL_DOWN_TIME_FOR_EMAIL_VERIFICATION_CODE_IN_SECONDS and
61
+ RESEND_COOL_DOWN_TIME_FOR_EMAIL_PASSWORD_RESET_CODE_IN_SECONDS in LOGIC section.
62
+ - profile
63
+ - add validation for email verification code already sent in send_verification_email_v0.
64
+ - add cooldown_reset_at in send_verification_email_v0 output.
65
+ - core
66
+ - add validation for email password reset code already sent in send_reset_password_email_v0.
67
+ - add cooldown_reset_at in send_reset_password_email_v0 output.
68
+
69
+ ### v9.0.0
70
+
71
+ - core
72
+ - **breaking change**: new mandatory parameter `app_id` in validate_and_get_payload_from_token_v0.
73
+
57
74
  ### v8.0.2
58
75
 
59
76
  - core