aiteamutils 0.2.76__py3-none-any.whl → 0.2.78__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- aiteamutils/base_model.py +3 -0
- aiteamutils/database.py +1 -1
- aiteamutils/security.py +16 -14
- aiteamutils/version.py +1 -1
- {aiteamutils-0.2.76.dist-info → aiteamutils-0.2.78.dist-info}/METADATA +1 -1
- {aiteamutils-0.2.76.dist-info → aiteamutils-0.2.78.dist-info}/RECORD +7 -7
- {aiteamutils-0.2.76.dist-info → aiteamutils-0.2.78.dist-info}/WHEEL +0 -0
aiteamutils/base_model.py
CHANGED
@@ -24,15 +24,18 @@ class BaseColumn(Base):
|
|
24
24
|
nullable=False
|
25
25
|
)
|
26
26
|
created_at: Mapped[datetime] = mapped_column(
|
27
|
+
TIMESTAMP(timezone=True),
|
27
28
|
default=datetime.now(timezone.utc),
|
28
29
|
index=True
|
29
30
|
)
|
30
31
|
updated_at: Mapped[datetime] = mapped_column(
|
32
|
+
TIMESTAMP(timezone=True),
|
31
33
|
default=datetime.now(timezone.utc),
|
32
34
|
onupdate=datetime.now(timezone.utc),
|
33
35
|
index=True
|
34
36
|
)
|
35
37
|
deleted_at: Mapped[datetime] = mapped_column(
|
38
|
+
TIMESTAMP(timezone=True),
|
36
39
|
default=None,
|
37
40
|
nullable=True
|
38
41
|
)
|
aiteamutils/database.py
CHANGED
aiteamutils/security.py
CHANGED
@@ -1,18 +1,19 @@
|
|
1
1
|
"""보안 관련 유틸리티."""
|
2
2
|
from datetime import datetime, timedelta, timezone
|
3
|
-
from typing import Dict, Any, Optional, Literal, Callable, TYPE_CHECKING
|
3
|
+
from typing import Dict, Any, Optional, Literal, Callable, TYPE_CHECKING, TypeVar, Type
|
4
4
|
from fastapi import Request, HTTPException, status
|
5
5
|
from functools import wraps
|
6
6
|
from jose import jwt, JWTError
|
7
7
|
from passlib.context import CryptContext
|
8
8
|
import logging
|
9
9
|
from sqlalchemy.ext.asyncio import AsyncSession
|
10
|
-
|
10
|
+
from sqlalchemy.orm import DeclarativeBase
|
11
11
|
from .exceptions import CustomException, ErrorCode
|
12
12
|
from .enums import ActivityType
|
13
13
|
from .database import log_create
|
14
14
|
|
15
15
|
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
16
|
+
ModelType = TypeVar("ModelType", bound=DeclarativeBase)
|
16
17
|
|
17
18
|
# 전역 rate limit 상태 저장
|
18
19
|
_rate_limits: Dict[str, Dict[str, Any]] = {}
|
@@ -133,7 +134,7 @@ def rate_limit(
|
|
133
134
|
return decorator
|
134
135
|
|
135
136
|
async def create_jwt_token(
|
136
|
-
user_data:
|
137
|
+
user_data: Type[ModelType],
|
137
138
|
token_type: Literal["access", "refresh"],
|
138
139
|
db_session: AsyncSession,
|
139
140
|
token_settings: Dict[str, Any],
|
@@ -207,19 +208,18 @@ async def create_jwt_token(
|
|
207
208
|
|
208
209
|
async def verify_jwt_token(
|
209
210
|
token: str,
|
210
|
-
expected_type: Optional[Literal["access", "refresh"]] = None
|
211
|
+
expected_type: Optional[Literal["access", "refresh"]] = None,
|
212
|
+
token_settings: Dict[str, Any] = None
|
211
213
|
) -> Dict[str, Any]:
|
212
214
|
"""JWT 토큰을 검증합니다."""
|
213
215
|
try:
|
214
|
-
settings = get_settings()
|
215
|
-
|
216
216
|
# 토큰 디코딩
|
217
217
|
payload = jwt.decode(
|
218
218
|
token,
|
219
|
-
|
220
|
-
algorithms=[
|
221
|
-
audience=
|
222
|
-
issuer=
|
219
|
+
token_settings["JWT_SECRET"],
|
220
|
+
algorithms=[token_settings["JWT_ALGORITHM"]],
|
221
|
+
audience=token_settings["TOKEN_AUDIENCE"],
|
222
|
+
issuer=token_settings["TOKEN_ISSUER"]
|
223
223
|
)
|
224
224
|
|
225
225
|
# 토큰 타입 검증
|
@@ -257,14 +257,16 @@ async def verify_jwt_token(
|
|
257
257
|
original_error=e
|
258
258
|
)
|
259
259
|
|
260
|
-
def validate_token(
|
260
|
+
def validate_token(
|
261
|
+
token: str,
|
262
|
+
token_settings: Dict[str, Any] = None
|
263
|
+
) -> Dict[str, Any]:
|
261
264
|
"""JWT 토큰을 검증하고 페이로드를 반환합니다."""
|
262
265
|
try:
|
263
|
-
settings = get_settings()
|
264
266
|
payload = jwt.decode(
|
265
267
|
token,
|
266
|
-
|
267
|
-
algorithms=[
|
268
|
+
token_settings["JWT_SECRET"],
|
269
|
+
algorithms=[token_settings["JWT_ALGORITHM"]]
|
268
270
|
)
|
269
271
|
return payload
|
270
272
|
except JWTError as e:
|
aiteamutils/version.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
"""버전 정보"""
|
2
|
-
__version__ = "0.2.
|
2
|
+
__version__ = "0.2.78"
|
@@ -1,15 +1,15 @@
|
|
1
1
|
aiteamutils/__init__.py,sha256=kRBpRjark0M8ZwFfmKiMFol6CbIILN3WE4f6_P6iIq0,1089
|
2
|
-
aiteamutils/base_model.py,sha256=
|
2
|
+
aiteamutils/base_model.py,sha256=bnRJJaGXGS3TKxfCWWV3arFjdG0qLsPFDXuguYsDyVM,3008
|
3
3
|
aiteamutils/base_repository.py,sha256=VLCLLVkNnYLmZ6EMcr3Tu0RkMqDyMhtCO3M_2j6q-R8,4409
|
4
4
|
aiteamutils/base_service.py,sha256=GmO_fqrSEbIs_Jc5BoRBTLfaJaS6CIxYPAs4B4TdtaU,9123
|
5
5
|
aiteamutils/cache.py,sha256=07xBGlgAwOTAdY5mnMOQJ5EBxVwe8glVD7DkGEkxCtw,1373
|
6
6
|
aiteamutils/config.py,sha256=YdalpJb70-txhGJAS4aaKglEZAFVWgfzw5BXSWpkUz4,3232
|
7
|
-
aiteamutils/database.py,sha256=
|
7
|
+
aiteamutils/database.py,sha256=Q2rwVfhS8Rpnj89EwtcLtmsDpANkJ1AlprlqQsgIQAg,19204
|
8
8
|
aiteamutils/enums.py,sha256=ipZi6k_QD5-3QV7Yzv7bnL0MjDz-vqfO9I5L77biMKs,632
|
9
9
|
aiteamutils/exceptions.py,sha256=3FUCIqXgYmMqonnMgUlh-J2xtApiiCgg4WM-2UV4vmQ,15823
|
10
|
-
aiteamutils/security.py,sha256=
|
10
|
+
aiteamutils/security.py,sha256=6rpRLh1mY6R1t-Ij0q5jTp6zl33ClqQsH8BFu8T4_EY,9762
|
11
11
|
aiteamutils/validators.py,sha256=PvI9hbMEAqTawgxPbiWRyx2r9yTUrpNBQs1AD3w4F2U,7726
|
12
|
-
aiteamutils/version.py,sha256=
|
13
|
-
aiteamutils-0.2.
|
14
|
-
aiteamutils-0.2.
|
15
|
-
aiteamutils-0.2.
|
12
|
+
aiteamutils/version.py,sha256=4hreD0PLKNdhKwNzr6cbGFmIvKZ63UUY7PvxlEaJsQU,42
|
13
|
+
aiteamutils-0.2.78.dist-info/METADATA,sha256=1VCxA1hJpW0i-L8CY4Jv5bVRMboL3pkhxUAc2o4SjtE,1718
|
14
|
+
aiteamutils-0.2.78.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
15
|
+
aiteamutils-0.2.78.dist-info/RECORD,,
|
File without changes
|