vanitha commited on
Commit
5fdb9fd
·
1 Parent(s): 42e40ce

changed user_id as UUID

Browse files
app/nosql.py CHANGED
@@ -41,7 +41,12 @@ class DatabaseConnection:
41
 
42
  logger.info(f"Connecting to MongoDB: {mongodb_uri}")
43
 
44
- cls._client = AsyncIOMotorClient(mongodb_uri)
 
 
 
 
 
45
  cls._db = cls._client[settings.MONGODB_DB_NAME]
46
 
47
  # Test the connection
 
41
 
42
  logger.info(f"Connecting to MongoDB: {mongodb_uri}")
43
 
44
+
45
+ cls._client = AsyncIOMotorClient(
46
+ mongodb_uri,
47
+ uuidRepresentation="standard"
48
+ )
49
+
50
  cls._db = cls._client[settings.MONGODB_DB_NAME]
51
 
52
  # Test the connection
app/system_users/controllers/router.py CHANGED
@@ -1,3 +1,4 @@
 
1
  from pydantic import BaseModel, Field
2
  from fastapi import APIRouter, Depends, HTTPException, status, Request
3
  from fastapi.security import HTTPAuthorizationCredentials
@@ -436,7 +437,7 @@ async def list_users_with_projection(
436
 
437
  @router.get("/users/{user_id}", response_model=UserInfoResponse)
438
  async def get_user_by_id(
439
- user_id: str,
440
  current_user: SystemUserModel = Depends(require_admin_role),
441
  user_service: SystemUserService = Depends(get_system_user_service)
442
  ):
@@ -480,7 +481,7 @@ async def get_user_by_id(
480
 
481
  @router.put("/users/{user_id}", response_model=UserInfoResponse)
482
  async def update_user(
483
- user_id: str,
484
  update_data: UpdateUserRequest,
485
  current_user: SystemUserModel = Depends(require_admin_role),
486
  user_service: SystemUserService = Depends(get_system_user_service)
@@ -764,7 +765,7 @@ async def reset_password(
764
 
765
  @router.delete("/users/{user_id}", response_model=StandardResponse)
766
  async def deactivate_user(
767
- user_id: str,
768
  current_user: SystemUserModel = Depends(require_admin_role),
769
  user_service: SystemUserService = Depends(get_system_user_service)
770
  ):
 
1
+ from uuid import UUID
2
  from pydantic import BaseModel, Field
3
  from fastapi import APIRouter, Depends, HTTPException, status, Request
4
  from fastapi.security import HTTPAuthorizationCredentials
 
437
 
438
  @router.get("/users/{user_id}", response_model=UserInfoResponse)
439
  async def get_user_by_id(
440
+ user_id: UUID,
441
  current_user: SystemUserModel = Depends(require_admin_role),
442
  user_service: SystemUserService = Depends(get_system_user_service)
443
  ):
 
481
 
482
  @router.put("/users/{user_id}", response_model=UserInfoResponse)
483
  async def update_user(
484
+ user_id: UUID,
485
  update_data: UpdateUserRequest,
486
  current_user: SystemUserModel = Depends(require_admin_role),
487
  user_service: SystemUserService = Depends(get_system_user_service)
 
765
 
766
  @router.delete("/users/{user_id}", response_model=StandardResponse)
767
  async def deactivate_user(
768
+ user_id: UUID,
769
  current_user: SystemUserModel = Depends(require_admin_role),
770
  user_service: SystemUserService = Depends(get_system_user_service)
771
  ):
app/system_users/models/model.py CHANGED
@@ -4,6 +4,7 @@ Represents a system user with login credentials and permissions.
4
  """
5
  from datetime import datetime
6
  from typing import Optional, Dict, Any, List
 
7
  from pydantic import BaseModel, Field, EmailStr
8
  from enum import Enum
9
 
@@ -53,7 +54,7 @@ class SystemUserModel(BaseModel):
53
  System User data model for authentication and authorization.
54
  Represents the complete user document in MongoDB.
55
  """
56
- user_id: str = Field(..., description="Unique user identifier (UUID/ULID)")
57
  username: str = Field(..., description="Unique username (lowercase alphanumeric)")
58
  email: EmailStr = Field(..., description="User email address")
59
  merchant_id: str = Field(..., description="User Merchant Information")
 
4
  """
5
  from datetime import datetime
6
  from typing import Optional, Dict, Any, List
7
+ from uuid import UUID
8
  from pydantic import BaseModel, Field, EmailStr
9
  from enum import Enum
10
 
 
54
  System User data model for authentication and authorization.
55
  Represents the complete user document in MongoDB.
56
  """
57
+ user_id: UUID = Field(..., description="Unique user identifier (UUID/ULID)")
58
  username: str = Field(..., description="Unique username (lowercase alphanumeric)")
59
  email: EmailStr = Field(..., description="User email address")
60
  merchant_id: str = Field(..., description="User Merchant Information")
app/system_users/schemas/schema.py CHANGED
@@ -3,6 +3,7 @@ System User schemas for request/response models.
3
  """
4
  from datetime import datetime
5
  from typing import Optional, List, Dict, Any
 
6
  from pydantic import BaseModel, Field, EmailStr, validator
7
  from app.system_users.models.model import UserStatus, UserRole
8
 
@@ -24,7 +25,7 @@ class LoginResponse(BaseModel):
24
 
25
  class UserInfoResponse(BaseModel):
26
  """User information response schema."""
27
- user_id: str = Field(..., description="Unique user identifier")
28
  username: str = Field(..., description="Username")
29
  email: str = Field(..., description="Email address")
30
  merchant_id: str = Field(..., description="Merchant ID")
 
3
  """
4
  from datetime import datetime
5
  from typing import Optional, List, Dict, Any
6
+ from uuid import UUID
7
  from pydantic import BaseModel, Field, EmailStr, validator
8
  from app.system_users.models.model import UserStatus, UserRole
9
 
 
25
 
26
  class UserInfoResponse(BaseModel):
27
  """User information response schema."""
28
+ user_id: UUID = Field(..., description="Unique user identifier")
29
  username: str = Field(..., description="Username")
30
  email: str = Field(..., description="Email address")
31
  merchant_id: str = Field(..., description="Merchant ID")
app/system_users/services/service.py CHANGED
@@ -4,6 +4,8 @@ System User service for authentication and user management.
4
  import secrets
5
  from datetime import datetime, timedelta
6
  from typing import Optional, List, Dict, Any, Tuple
 
 
7
  from motor.motor_asyncio import AsyncIOMotorDatabase
8
  from passlib.context import CryptContext
9
  from jose import JWTError, jwt
@@ -116,7 +118,7 @@ class SystemUserService:
116
  logger.warning(f"Token verification failed: {e}")
117
  return None
118
 
119
- async def get_user_by_id(self, user_id: str) -> Optional[SystemUserModel]:
120
  """Get user by user_id."""
121
  try:
122
  user_doc = await self.collection.find_one({"user_id": user_id})
@@ -179,8 +181,8 @@ class SystemUserService:
179
  )
180
 
181
  # Generate user ID
182
- user_id = f"usr_{secrets.token_urlsafe(16)}"
183
-
184
  # Hash password
185
  password_hash = self.get_password_hash(user_data.password)
186
 
@@ -194,7 +196,7 @@ class SystemUserService:
194
 
195
  # Create user model
196
  user_model = SystemUserModel(
197
- user_id=user_id,
198
  username=user_data.username.lower(),
199
  email=user_data.email.lower(),
200
  merchant_id=user_data.merchant_id,
@@ -206,12 +208,17 @@ class SystemUserService:
206
  role=user_data.role,
207
  permissions=user_data.permissions,
208
  status=UserStatus.ACTIVE, # Set as active by default
209
- created_by=created_by,
210
  created_at=datetime.utcnow()
211
  )
212
-
213
- # Insert to database
214
- await self.collection.insert_one(user_model.model_dump())
 
 
 
 
 
215
 
216
  logger.info(f"User created successfully: {user_id}")
217
  return user_model
@@ -470,7 +477,7 @@ class SystemUserService:
470
  "warning_threshold_days": warning_threshold
471
  }
472
 
473
- async def mark_password_change_required(self, user_id: str, reason: str = "password_rotation") -> bool:
474
  """
475
  Mark that a user must change their password.
476
 
@@ -519,7 +526,7 @@ class SystemUserService:
519
  logger.error(f"Error marking password change required for {user_id}: {e}")
520
  return False
521
 
522
- async def record_password_change(self, user_id: str, changed_by: str = "user") -> bool:
523
  """
524
  Record password change for rotation policy compliance.
525
 
@@ -593,7 +600,7 @@ class SystemUserService:
593
  logger.error(f"Error updating user {user_id}: {e}")
594
  return None
595
 
596
- async def change_password(self, user_id: str, current_password: str, new_password: str) -> bool:
597
  """Change user password."""
598
  try:
599
  user = await self.get_user_by_id(user_id)
 
4
  import secrets
5
  from datetime import datetime, timedelta
6
  from typing import Optional, List, Dict, Any, Tuple
7
+ from uuid import UUID
8
+ import uuid
9
  from motor.motor_asyncio import AsyncIOMotorDatabase
10
  from passlib.context import CryptContext
11
  from jose import JWTError, jwt
 
118
  logger.warning(f"Token verification failed: {e}")
119
  return None
120
 
121
+ async def get_user_by_id(self, user_id: UUID) -> Optional[SystemUserModel]:
122
  """Get user by user_id."""
123
  try:
124
  user_doc = await self.collection.find_one({"user_id": user_id})
 
181
  )
182
 
183
  # Generate user ID
184
+ # user_id = f"usr_{secrets.token_urlsafe(16)}"
185
+ user_id=str(uuid.uuid4())
186
  # Hash password
187
  password_hash = self.get_password_hash(user_data.password)
188
 
 
196
 
197
  # Create user model
198
  user_model = SystemUserModel(
199
+ user_id=str(user_id),
200
  username=user_data.username.lower(),
201
  email=user_data.email.lower(),
202
  merchant_id=user_data.merchant_id,
 
208
  role=user_data.role,
209
  permissions=user_data.permissions,
210
  status=UserStatus.ACTIVE, # Set as active by default
211
+ created_by=str(created_by),
212
  created_at=datetime.utcnow()
213
  )
214
+ doc = user_model.model_dump(by_alias=True, exclude_none=True)
215
+
216
+ # safety: convert UUID -> str if any slips through
217
+ for k, v in doc.items():
218
+ if isinstance(v, uuid.UUID):
219
+ doc[k] = str(v)
220
+
221
+ await self.collection.insert_one(doc)
222
 
223
  logger.info(f"User created successfully: {user_id}")
224
  return user_model
 
477
  "warning_threshold_days": warning_threshold
478
  }
479
 
480
+ async def mark_password_change_required(self, user_id: UUID, reason: str = "password_rotation") -> bool:
481
  """
482
  Mark that a user must change their password.
483
 
 
526
  logger.error(f"Error marking password change required for {user_id}: {e}")
527
  return False
528
 
529
+ async def record_password_change(self, user_id: UUID, changed_by: str = "user") -> bool:
530
  """
531
  Record password change for rotation policy compliance.
532
 
 
600
  logger.error(f"Error updating user {user_id}: {e}")
601
  return None
602
 
603
+ async def change_password(self, user_id: UUID, current_password: str, new_password: str) -> bool:
604
  """Change user password."""
605
  try:
606
  user = await self.get_user_by_id(user_id)