| 49 | |
| 50 | |
| 51 | async def create_user( |
| 52 | request: Request, |
| 53 | db_session: AsyncSession, |
| 54 | current_user: PublicUser | AnonymousUser, |
| 55 | user_object: UserCreate, |
| 56 | org_id: int, |
| 57 | is_oauth: bool = False, |
| 58 | signup_provider: str = "email", |
| 59 | ): |
| 60 | # Validate password complexity (skip for OAuth users who have empty passwords) |
| 61 | if user_object.password and not is_oauth: |
| 62 | validation_result = validate_password_complexity(user_object.password) |
| 63 | if not validation_result.is_valid: |
| 64 | raise HTTPException( |
| 65 | status_code=400, |
| 66 | detail={ |
| 67 | "code": "WEAK_PASSWORD", |
| 68 | "message": "Password does not meet security requirements", |
| 69 | "errors": validation_result.errors, |
| 70 | "requirements": validation_result.requirements, |
| 71 | }, |
| 72 | ) |
| 73 | |
| 74 | user = User.model_validate(user_object) |
| 75 | |
| 76 | # RBAC check |
| 77 | await rbac_check(request, current_user, "create", "user_x", db_session) |
| 78 | |
| 79 | # Complete the user object |
| 80 | user.user_uuid = f"user_{uuid4()}" |
| 81 | user.password = security_hash_password(user_object.password) if user_object.password else "" |
| 82 | |
| 83 | # OAuth users and OSS mode get auto-verified email |
| 84 | if is_oauth or get_deployment_mode() != 'saas': |
| 85 | user.email_verified = True |
| 86 | user.email_verified_at = datetime.now(timezone.utc).isoformat() |
| 87 | user.signup_method = signup_provider if is_oauth else "email" |
| 88 | else: |
| 89 | user.email_verified = False |
| 90 | user.email_verified_at = None |
| 91 | user.signup_method = "email" |
| 92 | |
| 93 | user.creation_date = str(datetime.now()) |
| 94 | user.update_date = str(datetime.now()) |
| 95 | |
| 96 | # Verifications |
| 97 | |
| 98 | # Check if Organization exists |
| 99 | statement = select(Organization).where(Organization.id == org_id) |
| 100 | result = (await db_session.execute(statement)).scalars().first() |
| 101 | |
| 102 | if not result: |
| 103 | raise HTTPException( |
| 104 | status_code=400, |
| 105 | detail="Organization does not exist", |
| 106 | ) |
| 107 | |
| 108 | # Usage check |