The ObjUser.yaml configuration file centralizes all SQL queries, configuration settings, and user group definitions used by the ObjUser class.
database:
connection: primary
schemas: {...} # Table schema references
queries: {...} # SQL query templates
configuration:
password: {...} # Password policy
auth: {...} # Authentication settings
defaults: {...} # User defaults
avatar: {...} # Avatar settings
standard_groups: {...} # Standard user groups
comments:
description: ... # File documentation
usage: ... # Usage examples
migration: ... # Migration guide
Before (inline SQL):
sql = f"""
SELECT *
FROM sys_user
WHERE User LIKE '{username}'
AND package = '{package}';
"""
self.sql_read_object(sql)
After (using yaml):
sql = self.load_yaml_query("read_by_username",
username=username,
package=package)
self.sql_read_object(sql)
Before:
Sql = f"""
select count(*) from sys_User_history where User = '{self._User}'
and package like '{package}'
and PasswordMessage like 'REGISTERED'
"""
Active = self.sql_get_int(Sql)
After:
sql = self.load_yaml_query("check_registered",
user=self._User,
package=package)
active = self.sql_get_int(sql)
Before:
sql = f"""
UPDATE sys_user SET
Lastinteraction = now()
WHERE
User like '{self._User}'
AND Package = '{self._Package}'
"""
self.sql_execute(sql)
After:
sql = self.load_yaml_query("update_lastinteraction",
user=self._User,
package=self._Package)
self.sql_execute(sql)
Before:
Sql = f"""
INSERT INTO sys_User_history (User, Password, Changetime, PasswordMessage, Package)
VALUES (
'{self._User}',
'{self._Password}',
'{str(self._Registerdate)}',
'{self._Passwordmessage}',
'{package}'
);
"""
self.sql_execute(Sql)
After:
sql = self.load_yaml_query("insert_history",
user=self._User,
password=self._Password,
changetime=str(self._Registerdate),
message=self._Passwordmessage,
package=package)
self.sql_execute(sql)
Before (hardcoded):
self.PasswordMinLen = 8
After (from yaml):
# In __init__
self.PasswordMinLen = self.get_yaml_config("password.min_length", 8)
Example accessing other config:
# Password policy
min_length = self.get_yaml_config("password.min_length", 8)
require_digit = self.get_yaml_config("password.require_digit", True)
max_age_days = self.get_yaml_config("password.max_age_days", 30)
# User defaults
default_level = self.get_yaml_config("defaults.level", 5)
default_group = self.get_yaml_config("defaults.user_group", "USER")
# Avatar settings
avatar_service = self.get_yaml_config("avatar.service")
avatar_size = self.get_yaml_config("avatar.size", "500x500")
# Standard groups
core_groups = self.get_yaml_config("standard_groups.core", [])
system_groups = self.get_yaml_config("standard_groups.system", [])
Before (hardcoded):
# In Create method
Sql = f"""
INSERT INTO sys_user (User, Package, Password,Uuid,Registerdate,Level, UserGroups)
VALUES ('{Email}','{package}','{Password}','{Uuid}',now(),5,'USER')
"""
After (using yaml config):
default_group = self.get_yaml_config("defaults.user_group", "USER")
sql = self.load_yaml_query("create_user",
email=Email,
package=package,
password=Password,
uuid=Uuid)
Validate against standard groups:
def validate_user_groups(self, groups_string):
"""Validate user groups against standard groups defined in yaml."""
all_standard_groups = []
# Get all standard groups from yaml
for category in ["core", "system", "workflow"]:
groups = self.get_yaml_config(f"standard_groups.{category}", [])
all_standard_groups.extend([g.upper() for g in groups])
# Parse user's groups
user_groups = [g.strip().upper() for g in groups_string.split(",")]
# Check each group
invalid_groups = [g for g in user_groups if g not in all_standard_groups]
if invalid_groups:
self.debug(f"Invalid groups: {invalid_groups}")
return False
return True
Before:
def ReviewLogin(self):
package = self.get_package()
Sql = f"""
select count(*) from sys_User_history where User = '{self._User}'
and package like '{package}'
and PasswordMessage like 'REGISTERED'
"""
Active = self.sql_get_int(Sql)
if Active == 0:
if not self._Registerdate:
self._Registerdate = self._Lastlogindate
StatusNote = "Registered"
self._Passwordmessage = StatusNote
Sql = f"""
INSERT INTO sys_User_history (User, Password, Changetime, PasswordMessage, Package)
VALUES (
'{self._User}',
'{self._Password}',
'{str(self._Registerdate)}',
'{self._Passwordmessage}',
'{package}'
);
"""
self.sql_execute(Sql)
# ... rest of method
After:
def ReviewLogin(self):
package = self.get_package()
# Check if user is registered
sql = self.load_yaml_query("check_registered",
user=self._User,
package=package)
active = self.sql_get_int(sql)
if active == 0:
if not self._Registerdate:
self._Registerdate = self._Lastlogindate
status_note = "Registered"
self._Passwordmessage = status_note
# Insert registration history
sql = self.load_yaml_query("insert_history",
user=self._User,
password=self._Password,
changetime=str(self._Registerdate),
message=self._Passwordmessage,
package=package)
self.sql_execute(sql)
# ... rest of method
def __init__(self, DB=0):
super().__init__(DB)
# Load configuration from yaml
self.PasswordMinLen = self.get_yaml_config("password.min_length", 8)
# Load other settings as needed
Start with the most frequently used queries:
read_by_username - User readsupdate_lastinteraction - Session trackinginsert_history - History loggingcheck_registered and check_activated - Status checksReplace hardcoded values:
After migrating each method:
Use Named Parameters: Always use named parameters in queries
# Good
sql = self.load_yaml_query("read_by_username", username=user, package=pkg)
# Bad (positional parameters - not supported)
sql = self.load_yaml_query("read_by_username", user, pkg)
Escape SQL Values: Use escape_sql() for user input
sql = self.load_yaml_query("read_by_username",
username=self.escape_sql(username),
package=package)
Default Values: Always provide defaults for config
min_len = self.get_yaml_config("password.min_length", 8) # Default: 8
Test Queries: Test queries independently before integration
# Test query loading
sql = self.load_yaml_query("read_by_username",
username="test",
package="test")
print(sql) # Verify output
# Test query loading
from factory.web.ObjUser import User
user = User()
# Test each query
queries = [
"read_by_username",
"check_registered",
"update_lastinteraction",
"insert_history"
]
for query_name in queries:
try:
sql = user.load_yaml_query(query_name,
user="test",
username="test",
package="test",
password="test",
changetime="2026-01-01",
message="test")
print(f"✓ {query_name}: OK")
except Exception as e:
print(f"✗ {query_name}: {e}")