aiteamutils 0.2.87__py3-none-any.whl → 0.2.89__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.
- aiteamutils/base_service.py +23 -7
- aiteamutils/exceptions.py +1 -0
- aiteamutils/security.py +21 -19
- aiteamutils/version.py +1 -1
- {aiteamutils-0.2.87.dist-info → aiteamutils-0.2.89.dist-info}/METADATA +1 -1
- {aiteamutils-0.2.87.dist-info → aiteamutils-0.2.89.dist-info}/RECORD +7 -7
- {aiteamutils-0.2.87.dist-info → aiteamutils-0.2.89.dist-info}/WHEEL +0 -0
aiteamutils/base_service.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#기본 라이브러리
|
2
2
|
from fastapi import Request
|
3
|
-
from typing import TypeVar, Generic, Type, Dict, Any, Union, List, Optional
|
3
|
+
from typing import TypeVar, Generic, Type, Dict, Any, Union, List, Optional, Literal
|
4
4
|
from sqlalchemy.orm import DeclarativeBase
|
5
5
|
from sqlalchemy.ext.asyncio import AsyncSession
|
6
6
|
from datetime import datetime
|
@@ -13,12 +13,12 @@ from .database import (
|
|
13
13
|
process_response,
|
14
14
|
validate_unique_fields
|
15
15
|
)
|
16
|
-
from .security import hash_password
|
16
|
+
from .security import hash_password, verify_jwt_token, verify_role_permission
|
17
17
|
ModelType = TypeVar("ModelType", bound=DeclarativeBase)
|
18
18
|
|
19
19
|
class BaseService(Generic[ModelType]):
|
20
20
|
##################
|
21
|
-
#
|
21
|
+
# 초기화 영역 #
|
22
22
|
##################
|
23
23
|
def __init__(
|
24
24
|
self,
|
@@ -37,12 +37,16 @@ class BaseService(Generic[ModelType]):
|
|
37
37
|
#######################
|
38
38
|
async def create(
|
39
39
|
self,
|
40
|
+
request: Request,
|
40
41
|
entity_data: Dict[str, Any],
|
41
42
|
response_model: Any = None,
|
42
43
|
exclude_entities: List[str] | None = None,
|
43
44
|
unique_check: List[Dict[str, Any]] | None = None,
|
44
45
|
fk_check: List[Dict[str, Any]] | None = None,
|
46
|
+
org_ulid_position: str = "organization_ulid",
|
47
|
+
role_permission: str = "create"
|
45
48
|
) -> ModelType:
|
49
|
+
await verify_role_permission(request, role_permission)
|
46
50
|
|
47
51
|
try:
|
48
52
|
async with self.db_session.begin():
|
@@ -77,12 +81,15 @@ class BaseService(Generic[ModelType]):
|
|
77
81
|
|
78
82
|
async def update(
|
79
83
|
self,
|
84
|
+
request: Request,
|
80
85
|
ulid: str | None = None,
|
81
86
|
update_data: Dict[str, Any] | None = None,
|
82
87
|
conditions: Dict[str, Any] | None = None,
|
83
88
|
unique_check: List[Dict[str, Any]] | None = None,
|
84
89
|
exclude_entities: List[str] | None = None,
|
85
|
-
response_model: Any = None
|
90
|
+
response_model: Any = None,
|
91
|
+
org_ulid_position: str = "organization_ulid",
|
92
|
+
role_permission: str = "update"
|
86
93
|
) -> ModelType:
|
87
94
|
try:
|
88
95
|
async with self.db_session.begin():
|
@@ -130,8 +137,11 @@ class BaseService(Generic[ModelType]):
|
|
130
137
|
|
131
138
|
async def delete(
|
132
139
|
self,
|
140
|
+
request: Request,
|
133
141
|
ulid: str | None = None,
|
134
|
-
conditions: Dict[str, Any] | None = None
|
142
|
+
conditions: Dict[str, Any] | None = None,
|
143
|
+
org_ulid_position: str = "organization_ulid",
|
144
|
+
role_permission: str = "delete"
|
135
145
|
) -> bool:
|
136
146
|
try:
|
137
147
|
if not ULID.from_str(ulid):
|
@@ -172,13 +182,16 @@ class BaseService(Generic[ModelType]):
|
|
172
182
|
#########################
|
173
183
|
async def list(
|
174
184
|
self,
|
185
|
+
request: Request,
|
175
186
|
skip: int = 0,
|
176
187
|
limit: int = 100,
|
177
188
|
filters: List[Dict[str, Any]] | None = None,
|
189
|
+
org_ulid_position: str = "organization_ulid",
|
178
190
|
response_model: Any = None,
|
179
191
|
explicit_joins: Optional[List[Any]] = None,
|
180
192
|
loading_joins: Optional[List[Any]] = None,
|
181
|
-
order: Optional[str] = None
|
193
|
+
order: Optional[str] = None,
|
194
|
+
role_permission: str = "list"
|
182
195
|
) -> List[Dict[str, Any]]:
|
183
196
|
try:
|
184
197
|
if order is None:
|
@@ -208,12 +221,15 @@ class BaseService(Generic[ModelType]):
|
|
208
221
|
|
209
222
|
async def get(
|
210
223
|
self,
|
224
|
+
request: Request,
|
211
225
|
ulid: str,
|
212
226
|
model_name: str | None = None,
|
213
227
|
response_model: Any = None,
|
214
228
|
conditions: Dict[str, Any] | None = None,
|
215
229
|
explicit_joins: Optional[List[Any]] = None,
|
216
|
-
loading_joins: Optional[List[Any]] = None
|
230
|
+
loading_joins: Optional[List[Any]] = None,
|
231
|
+
org_ulid_position: str = "organization_ulid",
|
232
|
+
role_permission: str = "get"
|
217
233
|
):
|
218
234
|
try:
|
219
235
|
if not ulid and not conditions:
|
aiteamutils/exceptions.py
CHANGED
@@ -25,6 +25,7 @@ class ErrorCode(Enum):
|
|
25
25
|
FORBIDDEN = ErrorResponse(1005, "AUTH_FORBIDDEN", 403, "접근 권한이 없습니다")
|
26
26
|
RATE_LIMIT_EXCEEDED = ErrorResponse(1006, "AUTH_RATE_LIMIT_EXCEEDED", 429, "너무 많은 요청이 발생했습니다")
|
27
27
|
INVALID_PASSWORD = ErrorResponse(1007, "AUTH_INVALID_PASSWORD", 401, "잘못된 비밀번호입니다")
|
28
|
+
INVALID_ROLE_PERMISSION = ErrorResponse(1008, "AUTH_INVALID_ROLE_PERMISSION", 401, "접근 권한이 없습니다")
|
28
29
|
|
29
30
|
# User 관련 에러: 2000번대
|
30
31
|
USER_NOT_FOUND = ErrorResponse(2001, "USER_NOT_FOUND", 404, "사용자를 찾을 수 없습니다")
|
aiteamutils/security.py
CHANGED
@@ -203,7 +203,6 @@ async def create_jwt_token(
|
|
203
203
|
original_error=str(e)
|
204
204
|
)
|
205
205
|
|
206
|
-
|
207
206
|
async def verify_jwt_token(
|
208
207
|
token: str,
|
209
208
|
expected_type: Optional[Literal["access", "refresh"]] = None,
|
@@ -283,22 +282,25 @@ async def verify_jwt_token(
|
|
283
282
|
original_error=e
|
284
283
|
)
|
285
284
|
|
286
|
-
def
|
287
|
-
|
288
|
-
|
289
|
-
) ->
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
token,
|
294
|
-
token_settings["JWT_SECRET"],
|
295
|
-
algorithms=[token_settings["JWT_ALGORITHM"]]
|
296
|
-
)
|
297
|
-
return payload
|
298
|
-
except JWTError as e:
|
285
|
+
async def verify_role_permission(
|
286
|
+
request: Request,
|
287
|
+
permission: str,
|
288
|
+
) -> bool:
|
289
|
+
token = request.headers.get("Authorization")
|
290
|
+
|
291
|
+
if not token:
|
299
292
|
raise CustomException(
|
300
|
-
ErrorCode.
|
301
|
-
detail=
|
302
|
-
source_function="security.
|
303
|
-
|
304
|
-
|
293
|
+
ErrorCode.UNAUTHORIZED,
|
294
|
+
detail="Authorization header is missing",
|
295
|
+
source_function="security.verify_role_permission"
|
296
|
+
)
|
297
|
+
|
298
|
+
token = token.split(" ")[1]
|
299
|
+
|
300
|
+
payload = await verify_jwt_token(token)
|
301
|
+
|
302
|
+
organization_ulid = payload.get("organization_ulid")
|
303
|
+
role_ulid = payload.get("role_ulid")
|
304
|
+
user_ulid = payload.get("user_ulid")
|
305
|
+
|
306
|
+
return True
|
aiteamutils/version.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
"""버전 정보"""
|
2
|
-
__version__ = "0.2.
|
2
|
+
__version__ = "0.2.89"
|
@@ -1,15 +1,15 @@
|
|
1
1
|
aiteamutils/__init__.py,sha256=kRBpRjark0M8ZwFfmKiMFol6CbIILN3WE4f6_P6iIq0,1089
|
2
2
|
aiteamutils/base_model.py,sha256=bnRJJaGXGS3TKxfCWWV3arFjdG0qLsPFDXuguYsDyVM,3008
|
3
3
|
aiteamutils/base_repository.py,sha256=HKcgYyEb0JypojoXBFcIT39hPC5CqnjBkHT__GV-lfQ,4615
|
4
|
-
aiteamutils/base_service.py,sha256=
|
4
|
+
aiteamutils/base_service.py,sha256=TlGIY4mkSmGq7Pqjz5ybGDCwpXicrSrs2LIFfjNKJqo,9404
|
5
5
|
aiteamutils/cache.py,sha256=07xBGlgAwOTAdY5mnMOQJ5EBxVwe8glVD7DkGEkxCtw,1373
|
6
6
|
aiteamutils/config.py,sha256=YdalpJb70-txhGJAS4aaKglEZAFVWgfzw5BXSWpkUz4,3232
|
7
7
|
aiteamutils/database.py,sha256=b4fN0XHNWxMJeS5M95JcJ7tujAJ1x3SPTAfDvJdB4sE,19696
|
8
8
|
aiteamutils/enums.py,sha256=Z9wzR3H4XLpA4U3urR5e4eDnEY3Qhne34nLXsKXiL64,2177
|
9
|
-
aiteamutils/exceptions.py,sha256=
|
10
|
-
aiteamutils/security.py,sha256=
|
9
|
+
aiteamutils/exceptions.py,sha256=wls-R8qbD7fWzEgDDY1Eiy1vXl59R5IsCXTRkZpBiGU,16021
|
10
|
+
aiteamutils/security.py,sha256=scyPjVAKXTlu7peGKtUgX-PhcteNWgDt-pDF46PLPy8,10850
|
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=qp3nB-yWKyYCX8Ttv3g_SDaDwxV5ldrepC0S131QqUg,42
|
13
|
+
aiteamutils-0.2.89.dist-info/METADATA,sha256=VLvXEYylcdpRHXATtaAFH0DyW5IKLcBHvnwxageKAcU,1718
|
14
|
+
aiteamutils-0.2.89.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
15
|
+
aiteamutils-0.2.89.dist-info/RECORD,,
|
File without changes
|