square-authentication 6.0.4__tar.gz → 6.1.0__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.
- {square_authentication-6.0.4 → square_authentication-6.1.0}/PKG-INFO +11 -1
- {square_authentication-6.0.4 → square_authentication-6.1.0}/README.md +10 -0
- {square_authentication-6.0.4 → square_authentication-6.1.0}/setup.py +1 -1
- {square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication/configuration.py +3 -0
- {square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication/data/config.ini +1 -0
- {square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication/data/config.testing.ini +1 -0
- {square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication/main.py +2 -1
- {square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication/messages.py +1 -0
- {square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication/routes/core.py +36 -0
- {square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication.egg-info/PKG-INFO +11 -1
- {square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication.egg-info/SOURCES.txt +2 -1
- square_authentication-6.1.0/tests/test_username.py +111 -0
- {square_authentication-6.0.4 → square_authentication-6.1.0}/setup.cfg +0 -0
- {square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication/__init__.py +0 -0
- {square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication/pydantic_models/__init__.py +0 -0
- {square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication/pydantic_models/core.py +0 -0
- {square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication/routes/__init__.py +0 -0
- {square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication/routes/profile.py +0 -0
- {square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication/routes/utility.py +0 -0
- {square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication/utils/__init__.py +0 -0
- {square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication/utils/encryption.py +0 -0
- {square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication/utils/token.py +0 -0
- {square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication.egg-info/dependency_links.txt +0 -0
- {square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication.egg-info/requires.txt +0 -0
- {square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication.egg-info/top_level.txt +0 -0
- {square_authentication-6.0.4 → square_authentication-6.1.0}/tests/test_1.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: square_authentication
|
3
|
-
Version: 6.0
|
3
|
+
Version: 6.1.0
|
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.1.0
|
57
|
+
|
58
|
+
- add validation to username in register_username_v0 and update_username_v0.
|
59
|
+
- add test cases for register_username_v0.
|
60
|
+
|
61
|
+
### v6.0.5
|
62
|
+
|
63
|
+
- env
|
64
|
+
- add ALLOW_ORIGINS
|
65
|
+
|
56
66
|
### v6.0.4
|
57
67
|
|
58
68
|
- mock ini file for pytest.
|
@@ -16,6 +16,16 @@ pip install square_authentication
|
|
16
16
|
|
17
17
|
## changelog
|
18
18
|
|
19
|
+
### v6.1.0
|
20
|
+
|
21
|
+
- add validation to username in register_username_v0 and update_username_v0.
|
22
|
+
- add test cases for register_username_v0.
|
23
|
+
|
24
|
+
### v6.0.5
|
25
|
+
|
26
|
+
- env
|
27
|
+
- add ALLOW_ORIGINS
|
28
|
+
|
19
29
|
### v6.0.4
|
20
30
|
|
21
31
|
- mock ini file for pytest.
|
{square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication/configuration.py
RENAMED
@@ -22,6 +22,9 @@ try:
|
|
22
22
|
# environment
|
23
23
|
config_str_host_ip = ldict_configuration["ENVIRONMENT"]["HOST_IP"]
|
24
24
|
config_int_host_port = int(ldict_configuration["ENVIRONMENT"]["HOST_PORT"])
|
25
|
+
config_list_allow_origins = eval(
|
26
|
+
ldict_configuration["ENVIRONMENT"]["ALLOW_ORIGINS"]
|
27
|
+
)
|
25
28
|
config_str_log_file_name = ldict_configuration["ENVIRONMENT"]["LOG_FILE_NAME"]
|
26
29
|
config_str_secret_key_for_access_token = ldict_configuration["ENVIRONMENT"][
|
27
30
|
"SECRET_KEY_FOR_ACCESS_TOKEN"
|
@@ -13,6 +13,7 @@ from square_authentication.configuration import (
|
|
13
13
|
config_str_module_name,
|
14
14
|
config_str_ssl_key_file_path,
|
15
15
|
config_str_ssl_crt_file_path,
|
16
|
+
config_list_allow_origins,
|
16
17
|
)
|
17
18
|
from square_authentication.routes import core, utility, profile
|
18
19
|
|
@@ -21,7 +22,7 @@ app = FastAPI()
|
|
21
22
|
app.add_middleware(
|
22
23
|
CORSMiddleware,
|
23
24
|
allow_credentials=True,
|
24
|
-
allow_origins=
|
25
|
+
allow_origins=config_list_allow_origins,
|
25
26
|
allow_methods=["*"],
|
26
27
|
allow_headers=["*"],
|
27
28
|
)
|
{square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication/messages.py
RENAMED
@@ -5,6 +5,7 @@ messages = {
|
|
5
5
|
"INCORRECT_USERNAME": "the username you entered does not exist.",
|
6
6
|
"INCORRECT_PASSWORD": "the password you entered is incorrect. please try again.",
|
7
7
|
"INCORRECT_USER_ID": "the user ID you provided does not exist or is invalid.",
|
8
|
+
"USERNAME_INVALID": "username must start and end with a lowercase letter and can include only lowercase letters, digits, underscores, or hyphens. no spaces, no dots, and no consecutive special characters.",
|
8
9
|
"USERNAME_ALREADY_EXISTS": "the username you entered is already taken. please choose a different one.",
|
9
10
|
"INCORRECT_ACCESS_TOKEN": "the access token provided is invalid or expired.",
|
10
11
|
"INCORRECT_REFRESH_TOKEN": "the refresh token provided is invalid or expired.",
|
{square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication/routes/core.py
RENAMED
@@ -1,4 +1,5 @@
|
|
1
1
|
import copy
|
2
|
+
import re
|
2
3
|
from datetime import datetime, timedelta, timezone
|
3
4
|
from typing import Annotated, List
|
4
5
|
|
@@ -67,6 +68,22 @@ async def register_username_v0(
|
|
67
68
|
validation
|
68
69
|
"""
|
69
70
|
# 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]$")
|
76
|
+
if not username_pattern.match(username):
|
77
|
+
output_content = get_api_output_in_standard_format(
|
78
|
+
message=messages["USERNAME_INVALID"],
|
79
|
+
log=f"username '{username}' is invalid. it must start and end with a letter, "
|
80
|
+
f"contain only lowercase letters, numbers, underscores, or hyphens, "
|
81
|
+
f"and not have consecutive separators.",
|
82
|
+
)
|
83
|
+
raise HTTPException(
|
84
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
85
|
+
detail=output_content,
|
86
|
+
)
|
70
87
|
local_list_response_user_creds = (
|
71
88
|
global_object_square_database_helper.get_rows_v0(
|
72
89
|
database_name=global_string_database_name,
|
@@ -1098,6 +1115,25 @@ async def update_username_v0(
|
|
1098
1115
|
)
|
1099
1116
|
user_id = local_dict_access_token_payload["user_id"]
|
1100
1117
|
|
1118
|
+
# 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
|
+
new_username = new_username.lower()
|
1124
|
+
username_pattern = re.compile(r"^(?!.*[._-]{2})[a-z][a-z0-9_-]{1,18}[a-z]$")
|
1125
|
+
if not username_pattern.match(new_username):
|
1126
|
+
output_content = get_api_output_in_standard_format(
|
1127
|
+
message=messages["USERNAME_INVALID"],
|
1128
|
+
log=f"username '{new_username}' is invalid. it must start and end with a letter, "
|
1129
|
+
f"contain only lowercase letters, numbers, underscores, or hyphens, "
|
1130
|
+
f"and not have consecutive separators.",
|
1131
|
+
)
|
1132
|
+
raise HTTPException(
|
1133
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
1134
|
+
detail=output_content,
|
1135
|
+
)
|
1136
|
+
|
1101
1137
|
# validate user_id
|
1102
1138
|
local_list_user_response = global_object_square_database_helper.get_rows_v0(
|
1103
1139
|
database_name=global_string_database_name,
|
{square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication.egg-info/PKG-INFO
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: square_authentication
|
3
|
-
Version: 6.0
|
3
|
+
Version: 6.1.0
|
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.1.0
|
57
|
+
|
58
|
+
- add validation to username in register_username_v0 and update_username_v0.
|
59
|
+
- add test cases for register_username_v0.
|
60
|
+
|
61
|
+
### v6.0.5
|
62
|
+
|
63
|
+
- env
|
64
|
+
- add ALLOW_ORIGINS
|
65
|
+
|
56
66
|
### v6.0.4
|
57
67
|
|
58
68
|
- mock ini file for pytest.
|
@@ -0,0 +1,111 @@
|
|
1
|
+
from square_authentication.messages import messages
|
2
|
+
|
3
|
+
|
4
|
+
def test_register_username_invalid(create_client_and_cleanup):
|
5
|
+
payload = {
|
6
|
+
"username": "invalid..name",
|
7
|
+
"password": "testpass123",
|
8
|
+
"app_id": 1,
|
9
|
+
}
|
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"]
|
13
|
+
|
14
|
+
|
15
|
+
def test_username_starts_with_number(create_client_and_cleanup):
|
16
|
+
payload = {
|
17
|
+
"username": "1username",
|
18
|
+
"password": "testpass123",
|
19
|
+
"app_id": 1,
|
20
|
+
}
|
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"]
|
24
|
+
|
25
|
+
|
26
|
+
def test_username_ends_with_number(create_client_and_cleanup):
|
27
|
+
payload = {
|
28
|
+
"username": "username1",
|
29
|
+
"password": "testpass123",
|
30
|
+
"app_id": 1,
|
31
|
+
}
|
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"]
|
35
|
+
|
36
|
+
|
37
|
+
def test_username_with_space(create_client_and_cleanup):
|
38
|
+
payload = {
|
39
|
+
"username": "user name",
|
40
|
+
"password": "testpass123",
|
41
|
+
"app_id": 1,
|
42
|
+
}
|
43
|
+
response = create_client_and_cleanup.post("/register_username/v0", json=payload)
|
44
|
+
assert response.status_code == 400
|
45
|
+
assert "username" in response.json()["log"]
|
46
|
+
|
47
|
+
|
48
|
+
def test_username_too_short(create_client_and_cleanup):
|
49
|
+
payload = {
|
50
|
+
"username": "a",
|
51
|
+
"password": "testpass123",
|
52
|
+
"app_id": 1,
|
53
|
+
}
|
54
|
+
response = create_client_and_cleanup.post("/register_username/v0", json=payload)
|
55
|
+
assert response.status_code == 400
|
56
|
+
assert "username" in response.json()["log"]
|
57
|
+
|
58
|
+
|
59
|
+
def test_username_simple_valid(create_client_and_cleanup):
|
60
|
+
payload = {
|
61
|
+
"username": "johnsmith",
|
62
|
+
"password": "testpass123",
|
63
|
+
"app_id": 1,
|
64
|
+
}
|
65
|
+
response = create_client_and_cleanup.post("/register_username/v0", json=payload)
|
66
|
+
assert response.status_code == 201
|
67
|
+
assert response.json()["message"] == messages["REGISTRATION_SUCCESSFUL"]
|
68
|
+
|
69
|
+
|
70
|
+
def test_username_with_uppercase(create_client_and_cleanup):
|
71
|
+
payload = {
|
72
|
+
"username": "User_Name",
|
73
|
+
"password": "testpass123",
|
74
|
+
"app_id": 1,
|
75
|
+
}
|
76
|
+
response = create_client_and_cleanup.post("/register_username/v0", json=payload)
|
77
|
+
assert response.status_code == 201
|
78
|
+
assert response.json()["message"] == messages["REGISTRATION_SUCCESSFUL"]
|
79
|
+
|
80
|
+
|
81
|
+
def test_username_with_digits(create_client_and_cleanup):
|
82
|
+
payload = {
|
83
|
+
"username": "john123smith",
|
84
|
+
"password": "testpass123",
|
85
|
+
"app_id": 1,
|
86
|
+
}
|
87
|
+
response = create_client_and_cleanup.post("/register_username/v0", json=payload)
|
88
|
+
assert response.status_code == 201
|
89
|
+
assert response.json()["message"] == messages["REGISTRATION_SUCCESSFUL"]
|
90
|
+
|
91
|
+
|
92
|
+
def test_username_with_underscore_hyphen(create_client_and_cleanup):
|
93
|
+
payload = {
|
94
|
+
"username": "john_smith-doe",
|
95
|
+
"password": "testpass123",
|
96
|
+
"app_id": 1,
|
97
|
+
}
|
98
|
+
response = create_client_and_cleanup.post("/register_username/v0", json=payload)
|
99
|
+
assert response.status_code == 201
|
100
|
+
assert response.json()["message"] == messages["REGISTRATION_SUCCESSFUL"]
|
101
|
+
|
102
|
+
|
103
|
+
def test_username_max_length(create_client_and_cleanup):
|
104
|
+
payload = {
|
105
|
+
"username": "a1234567890_b-cdefgh",
|
106
|
+
"password": "testpass123",
|
107
|
+
"app_id": 1,
|
108
|
+
}
|
109
|
+
response = create_client_and_cleanup.post("/register_username/v0", json=payload)
|
110
|
+
assert response.status_code == 201
|
111
|
+
assert response.json()["message"] == messages["REGISTRATION_SUCCESSFUL"]
|
File without changes
|
{square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication/routes/__init__.py
RENAMED
File without changes
|
{square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication/routes/profile.py
RENAMED
File without changes
|
{square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication/routes/utility.py
RENAMED
File without changes
|
{square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication/utils/__init__.py
RENAMED
File without changes
|
File without changes
|
{square_authentication-6.0.4 → square_authentication-6.1.0}/square_authentication/utils/token.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|