Spaces:
Running
Running
Commit Β·
eb862e9
1
Parent(s): 7e4a9fd
feat: implement user migration and update role handling in database initialization
Browse files- app/core/db_init.py +62 -3
- app/system_users/models/model.py +3 -2
app/core/db_init.py
CHANGED
|
@@ -19,6 +19,9 @@ async def initialize_database():
|
|
| 19 |
try:
|
| 20 |
db = await get_database()
|
| 21 |
|
|
|
|
|
|
|
|
|
|
| 22 |
# Create default roles
|
| 23 |
await create_default_roles(db)
|
| 24 |
|
|
@@ -32,6 +35,46 @@ async def initialize_database():
|
|
| 32 |
raise
|
| 33 |
|
| 34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
async def create_default_roles(db):
|
| 36 |
"""Create default access roles."""
|
| 37 |
roles_collection = db[AUTH_ACCESS_ROLES_COLLECTION]
|
|
@@ -105,7 +148,7 @@ async def create_initial_users(db):
|
|
| 105 |
"first_name": "Super",
|
| 106 |
"last_name": "Admin",
|
| 107 |
"phone": "+919999999999",
|
| 108 |
-
"
|
| 109 |
"permissions": {
|
| 110 |
"users": ["view", "create", "update", "delete"],
|
| 111 |
"roles": ["view", "create", "update", "delete"],
|
|
@@ -132,7 +175,7 @@ async def create_initial_users(db):
|
|
| 132 |
"first_name": "Company",
|
| 133 |
"last_name": "Admin",
|
| 134 |
"phone": "+919999999998",
|
| 135 |
-
"
|
| 136 |
"permissions": {
|
| 137 |
"users": ["view", "create", "update"],
|
| 138 |
"roles": ["view"],
|
|
@@ -158,7 +201,23 @@ async def create_initial_users(db):
|
|
| 158 |
await users_collection.insert_one(user)
|
| 159 |
logger.info(f" β Created user: {user['email']}")
|
| 160 |
else:
|
| 161 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 162 |
|
| 163 |
logger.info("\nπ Default Credentials:")
|
| 164 |
logger.info(" superadmin@cuatrolabs.com / SuperAdmin@123")
|
|
|
|
| 19 |
try:
|
| 20 |
db = await get_database()
|
| 21 |
|
| 22 |
+
# Migrate existing data
|
| 23 |
+
await migrate_existing_users(db)
|
| 24 |
+
|
| 25 |
# Create default roles
|
| 26 |
await create_default_roles(db)
|
| 27 |
|
|
|
|
| 35 |
raise
|
| 36 |
|
| 37 |
|
| 38 |
+
async def migrate_existing_users(db):
|
| 39 |
+
"""Migrate existing users to add missing required fields."""
|
| 40 |
+
logger.info("π Migrating existing users...")
|
| 41 |
+
users_collection = db[AUTH_SYSTEM_USERS_COLLECTION]
|
| 42 |
+
|
| 43 |
+
try:
|
| 44 |
+
# Add role_id field to users missing it
|
| 45 |
+
result = await users_collection.update_many(
|
| 46 |
+
{"role_id": {"$exists": False}},
|
| 47 |
+
{"$set": {"role_id": "user"}}
|
| 48 |
+
)
|
| 49 |
+
if result.modified_count > 0:
|
| 50 |
+
logger.info(f" β Added role_id field to {result.modified_count} users")
|
| 51 |
+
|
| 52 |
+
# Ensure status field exists
|
| 53 |
+
result = await users_collection.update_many(
|
| 54 |
+
{"status": {"$exists": False}},
|
| 55 |
+
{"$set": {"status": "active"}}
|
| 56 |
+
)
|
| 57 |
+
if result.modified_count > 0:
|
| 58 |
+
logger.info(f" β Added status field to {result.modified_count} users")
|
| 59 |
+
|
| 60 |
+
# Ensure security_settings exists
|
| 61 |
+
result = await users_collection.update_many(
|
| 62 |
+
{"security_settings": {"$exists": False}},
|
| 63 |
+
{"$set": {
|
| 64 |
+
"security_settings": {
|
| 65 |
+
"require_password_change": False,
|
| 66 |
+
"failed_login_attempts": 0,
|
| 67 |
+
"login_attempts": []
|
| 68 |
+
}
|
| 69 |
+
}}
|
| 70 |
+
)
|
| 71 |
+
if result.modified_count > 0:
|
| 72 |
+
logger.info(f" β Added security_settings to {result.modified_count} users")
|
| 73 |
+
|
| 74 |
+
except Exception as e:
|
| 75 |
+
logger.warning(f"β Migration warning: {e}")
|
| 76 |
+
|
| 77 |
+
|
| 78 |
async def create_default_roles(db):
|
| 79 |
"""Create default access roles."""
|
| 80 |
roles_collection = db[AUTH_ACCESS_ROLES_COLLECTION]
|
|
|
|
| 148 |
"first_name": "Super",
|
| 149 |
"last_name": "Admin",
|
| 150 |
"phone": "+919999999999",
|
| 151 |
+
"role_id": "role_super_admin",
|
| 152 |
"permissions": {
|
| 153 |
"users": ["view", "create", "update", "delete"],
|
| 154 |
"roles": ["view", "create", "update", "delete"],
|
|
|
|
| 175 |
"first_name": "Company",
|
| 176 |
"last_name": "Admin",
|
| 177 |
"phone": "+919999999998",
|
| 178 |
+
"role_id": "role_company_admin",
|
| 179 |
"permissions": {
|
| 180 |
"users": ["view", "create", "update"],
|
| 181 |
"roles": ["view"],
|
|
|
|
| 201 |
await users_collection.insert_one(user)
|
| 202 |
logger.info(f" β Created user: {user['email']}")
|
| 203 |
else:
|
| 204 |
+
# Update existing user if missing required fields
|
| 205 |
+
updates = {}
|
| 206 |
+
if "role" not in existing:
|
| 207 |
+
updates["role"] = user["role"]
|
| 208 |
+
if "status" not in existing:
|
| 209 |
+
updates["status"] = "active"
|
| 210 |
+
if "security_settings" not in existing:
|
| 211 |
+
updates["security_settings"] = user["security_settings"]
|
| 212 |
+
|
| 213 |
+
if updates:
|
| 214 |
+
await users_collection.update_one(
|
| 215 |
+
{"email": user["email"]},
|
| 216 |
+
{"$set": updates}
|
| 217 |
+
)
|
| 218 |
+
logger.info(f" β Updated existing user: {user['email']} (added missing fields)")
|
| 219 |
+
else:
|
| 220 |
+
logger.info(f" β³ User exists: {user['email']}")
|
| 221 |
|
| 222 |
logger.info("\nπ Default Credentials:")
|
| 223 |
logger.info(" superadmin@cuatrolabs.com / SuperAdmin@123")
|
app/system_users/models/model.py
CHANGED
|
@@ -64,7 +64,7 @@ class SystemUserModel(BaseModel):
|
|
| 64 |
phone: Optional[str] = Field(None, description="User phone number (E.164 format)")
|
| 65 |
|
| 66 |
# Authorization
|
| 67 |
-
role: str = Field(
|
| 68 |
permissions: Dict[str, List[str]] = Field(default_factory=dict, description="Grouped permissions by module")
|
| 69 |
|
| 70 |
# Status and security
|
|
@@ -94,6 +94,7 @@ class SystemUserModel(BaseModel):
|
|
| 94 |
metadata: Optional[Dict[str, Any]] = Field(None, description="Additional metadata")
|
| 95 |
|
| 96 |
class Config:
|
|
|
|
| 97 |
json_schema_extra = {
|
| 98 |
"example": {
|
| 99 |
"user_id": "usr_01HZQX5K3N2P8R6T4V9W",
|
|
@@ -103,7 +104,7 @@ class SystemUserModel(BaseModel):
|
|
| 103 |
"first_name": "John",
|
| 104 |
"last_name": "Doe",
|
| 105 |
"phone": "+919876543210",
|
| 106 |
-
"
|
| 107 |
"permissions": {
|
| 108 |
"customers": ["view", "create", "update"],
|
| 109 |
"orders": ["view", "create", "update"],
|
|
|
|
| 64 |
phone: Optional[str] = Field(None, description="User phone number (E.164 format)")
|
| 65 |
|
| 66 |
# Authorization
|
| 67 |
+
role: str = Field(default="user", alias="role_id", description="User role identifier")
|
| 68 |
permissions: Dict[str, List[str]] = Field(default_factory=dict, description="Grouped permissions by module")
|
| 69 |
|
| 70 |
# Status and security
|
|
|
|
| 94 |
metadata: Optional[Dict[str, Any]] = Field(None, description="Additional metadata")
|
| 95 |
|
| 96 |
class Config:
|
| 97 |
+
populate_by_name = True
|
| 98 |
json_schema_extra = {
|
| 99 |
"example": {
|
| 100 |
"user_id": "usr_01HZQX5K3N2P8R6T4V9W",
|
|
|
|
| 104 |
"first_name": "John",
|
| 105 |
"last_name": "Doe",
|
| 106 |
"phone": "+919876543210",
|
| 107 |
+
"role_id": "admin",
|
| 108 |
"permissions": {
|
| 109 |
"customers": ["view", "create", "update"],
|
| 110 |
"orders": ["view", "create", "update"],
|