trovesuite 1.0.17__py3-none-any.whl → 1.0.19__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.
@@ -72,7 +72,7 @@ class AuthService:
72
72
  try:
73
73
 
74
74
  is_tenant_verified = DatabaseManager.execute_query(
75
- f"SELECT is_verified FROM {db_settings.MAIN_TENANTS_TABLE} WHERE delete_status = 'NOT_DELETED' AND id = %s",
75
+ f"SELECT is_verified FROM {db_settings.CORE_PLATFORM_TENANTS_TABLE} WHERE delete_status = 'NOT_DELETED' AND id = %s",
76
76
  (tenant_id,),
77
77
  )
78
78
 
@@ -98,8 +98,9 @@ class AuthService:
98
98
 
99
99
  # 1️⃣ Get all groups the user belongs to
100
100
  user_groups = DatabaseManager.execute_query(
101
- f"""SELECT group_id FROM "{tenant_id}".{db_settings.TENANT_USER_GROUPS_TABLE}
102
- WHERE delete_status = 'NOT_DELETED' AND is_active = true AND user_id = %s""",(user_id,),
101
+ f"""SELECT group_id FROM {db_settings.CORE_PLATFORM_USER_GROUPS_TABLE}
102
+ WHERE tenant_id = %s AND delete_status = 'NOT_DELETED' AND is_active = true AND user_id = %s AND (is_system = false OR is_system IS NULL)""",
103
+ (tenant_id, user_id,),
103
104
  )
104
105
 
105
106
  # 2️⃣ Prepare list of group_ids
@@ -110,20 +111,20 @@ class AuthService:
110
111
  login_settings_details = DatabaseManager.execute_query(
111
112
  f"""SELECT user_id, group_id, is_suspended, can_always_login,
112
113
  is_multi_factor_enabled, is_login_before, working_days,
113
- login_on, logout_on FROM "{tenant_id}".{db_settings.TENANT_LOGIN_SETTINGS_TABLE}
114
- WHERE (delete_status = 'NOT_DELETED' AND is_active = true )
114
+ login_on, logout_on FROM {db_settings.CORE_PLATFORM_LOGIN_SETTINGS_TABLE}
115
+ WHERE tenant_id = %s AND (delete_status = 'NOT_DELETED' AND is_active = true )
115
116
  AND (user_id = %s OR group_id = ANY(%s))
116
117
  ORDER BY user_id NULLS LAST
117
118
  LIMIT 1""",
118
- (user_id, group_ids),
119
+ (tenant_id, user_id, group_ids),
119
120
  )
120
121
  else:
121
122
  login_settings_details = DatabaseManager.execute_query(
122
123
  f"""SELECT user_id, group_id, is_suspended, can_always_login,
123
124
  is_multi_factor_enabled, is_login_before, working_days,
124
- login_on, logout_on FROM "{tenant_id}".{db_settings.TENANT_LOGIN_SETTINGS_TABLE}
125
- WHERE (delete_status = 'NOT_DELETED' AND is_active = true ) AND user_id = %s""",
126
- (user_id,),
125
+ login_on, logout_on FROM {db_settings.CORE_PLATFORM_LOGIN_SETTINGS_TABLE}
126
+ WHERE tenant_id = %s AND (delete_status = 'NOT_DELETED' AND is_active = true ) AND user_id = %s""",
127
+ (tenant_id, user_id,),
127
128
  )
128
129
 
129
130
  if not login_settings_details or len(login_settings_details) == 0:
@@ -158,6 +159,7 @@ class AuthService:
158
159
  # 2. time period restriction (if login_on/logout_on are set)
159
160
 
160
161
  if login_on and logout_on:
162
+
161
163
  # Time period restriction is active
162
164
  logger.info(f"Checking time period restriction for user: {user_id}")
163
165
 
@@ -202,13 +204,14 @@ class AuthService:
202
204
  f"""
203
205
  SELECT DISTINCT ON (group_id, user_id, role_id)
204
206
  group_id, user_id, role_id, resource_type
205
- FROM "{tenant_id}".{db_settings.TENANT_ASSIGN_ROLES_TABLE}
206
- WHERE delete_status = 'NOT_DELETED'
207
+ FROM {db_settings.CORE_PLATFORM_ASSIGN_ROLES_TABLE}
208
+ WHERE tenant_id = %s AND delete_status = 'NOT_DELETED'
207
209
  AND is_active = true
210
+ AND (is_system = false OR is_system IS NULL)
208
211
  AND (user_id = %s OR group_id = ANY(%s))
209
212
  ORDER BY group_id, user_id, role_id;
210
213
  """,
211
- (user_id, group_ids),
214
+ (tenant_id, user_id, group_ids),
212
215
  )
213
216
  else:
214
217
  # No groups, just check roles for user
@@ -216,28 +219,36 @@ class AuthService:
216
219
  f"""
217
220
  SELECT DISTINCT ON (user_id, role_id)
218
221
  user_id, role_id, resource_type
219
- FROM "{tenant_id}".{db_settings.TENANT_ASSIGN_ROLES_TABLE}
220
- WHERE delete_status = 'NOT_DELETED'
222
+ FROM {db_settings.CORE_PLATFORM_ASSIGN_ROLES_TABLE}
223
+ WHERE tenant_id = %s AND delete_status = 'NOT_DELETED'
221
224
  AND is_active = true
225
+ AND (is_system = false OR is_system IS NULL)
222
226
  AND user_id = %s
223
227
  ORDER BY user_id, role_id;
224
228
  """,
225
- (user_id,),
229
+ (tenant_id, user_id,),
226
230
  )
227
231
 
228
- # ✅ NEW: Get system-level roles from main.system_user_groups and main.system_assign_roles
232
+ # ✅ NEW: Get system-level roles from cp_user_groups and cp_assign_roles with is_system=true
233
+ # NOTE: system_groups, system_user_groups, and system_assign_roles are now consolidated
234
+ # into cp_groups, cp_user_groups, and cp_assign_roles with is_system flag
229
235
  logger.info(f"Fetching system-level roles for user: {user_id}")
230
236
 
231
237
  system_roles = DatabaseManager.execute_query(
232
238
  f"""
233
239
  SELECT DISTINCT sug.group_id, sug.user_id, sar.role_id, sar.resource_type
234
- FROM {db_settings.MAIN_SYSTEM_USER_GROUPS_TABLE} sug
235
- INNER JOIN {db_settings.MAIN_SYSTEM_ASSIGN_ROLES_TABLE} sar ON sug.group_id = sar.group_id
236
- WHERE sug.user_id = %s
240
+ FROM {db_settings.CORE_PLATFORM_SYSTEM_USER_GROUPS_TABLE} sug
241
+ INNER JOIN {db_settings.CORE_PLATFORM_SYSTEM_ASSIGN_ROLES_TABLE} sar
242
+ ON sug.group_id = sar.group_id AND sug.tenant_id = sar.tenant_id
243
+ WHERE sug.user_id = %s AND sug.tenant_id = %s
244
+ AND sug.is_system = true
245
+ AND sug.is_active = true
246
+ AND sug.delete_status = 'NOT_DELETED'
237
247
  AND sar.is_active = true
238
248
  AND sar.delete_status = 'NOT_DELETED'
249
+ AND sar.is_system = true
239
250
  """,
240
- (user_id,)
251
+ (user_id, 'system-tenant-id')
241
252
  )
242
253
 
243
254
  if system_roles:
@@ -245,16 +256,17 @@ class AuthService:
245
256
  else:
246
257
  logger.info(f"No system-level roles found for user: {user_id}")
247
258
 
248
- # ✅ NEW: Also check for direct system role assignments (user_id in system_assign_roles)
259
+ # ✅ NEW: Also check for direct system role assignments (user_id in cp_assign_roles with is_system=true)
249
260
  direct_system_roles = DatabaseManager.execute_query(
250
261
  f"""
251
262
  SELECT DISTINCT NULL as group_id, sar.user_id, sar.role_id, sar.resource_type
252
- FROM {db_settings.MAIN_SYSTEM_ASSIGN_ROLES_TABLE} sar
253
- WHERE sar.user_id = %s
263
+ FROM {db_settings.CORE_PLATFORM_SYSTEM_ASSIGN_ROLES_TABLE} sar
264
+ WHERE sar.user_id = %s AND sar.tenant_id = %s
254
265
  AND sar.is_active = true
255
266
  AND sar.delete_status = 'NOT_DELETED'
267
+ AND sar.is_system = true
256
268
  """,
257
- (user_id,)
269
+ (user_id, 'system-tenant-id')
258
270
  )
259
271
 
260
272
  if direct_system_roles:
@@ -267,10 +279,23 @@ class AuthService:
267
279
 
268
280
  # GET permissions and Append to Role
269
281
  get_user_roles_with_tenant_and_permissions = []
282
+ # Track system role IDs for quick lookup
283
+ system_role_ids = {r["role_id"] for r in system_roles} if system_roles else set()
284
+ if direct_system_roles:
285
+ system_role_ids.update({r["role_id"] for r in direct_system_roles})
286
+
270
287
  for role in all_roles:
288
+ role_id = role["role_id"]
289
+ # For system roles, use system-tenant-id; for tenant roles, use tenant_id
290
+ if role_id in system_role_ids:
291
+ role_tenant_id = 'system-tenant-id'
292
+ else:
293
+ role_tenant_id = tenant_id
294
+
271
295
  permissions = DatabaseManager.execute_query(
272
- f"""SELECT permission_id FROM {db_settings.MAIN_ROLE_PERMISSIONS_TABLE} WHERE role_id = %s""",
273
- params=(role["role_id"],),
296
+ f"""SELECT permission_id FROM {db_settings.CORE_PLATFORM_ROLE_PERMISSIONS_TABLE}
297
+ WHERE role_id = %s AND tenant_id = %s""",
298
+ params=(role_id, role_tenant_id),
274
299
  )
275
300
 
276
301
  role_dict = {**role, "tenant_id": tenant_id, "permissions": [p['permission_id'] for p in permissions]}
@@ -301,7 +326,6 @@ class AuthService:
301
326
  error="Authorization check failed due to an internal error"
302
327
  )
303
328
 
304
-
305
329
  @staticmethod
306
330
  def check_permission(users_data: list, action=None, resource_type=None) -> bool:
307
331
  """
@@ -10,6 +10,11 @@ class Settings:
10
10
  DB_PORT: str = os.getenv("DB_PORT")
11
11
  DB_PASSWORD: str = os.getenv("DB_PASSWORD")
12
12
 
13
+ # CORS Endpoint
14
+ # LOCAL_HOST_URL = os.getenv("LOCAL_HOST_URL")
15
+ # FRONTEND_SERVER_URL_1 = os.getenv("FRONTEND_SERVER_URL")
16
+ # FRONTEND_SERVER_URL_2 = os.getenv("FRONTEND_SERVER_URL")
17
+
13
18
  # Application settings
14
19
  DEBUG: bool = os.getenv("DEBUG", "True").lower() in ("true",1)
15
20
  APP_NAME: str = os.getenv("APP_NAME", "Python Template API")
@@ -30,53 +35,52 @@ class Settings:
30
35
  ACCESS_TOKEN_EXPIRE_MINUTES: int = int(os.getenv("ACCESS_TOKEN_EXPIRE_MINUTES", "120"))
31
36
 
32
37
  # =============================================================================
33
- # SHARED TABLES (main schema)
38
+ # SHARED TABLES (core_platform schema)
34
39
  # =============================================================================
35
- MAIN_TENANTS_TABLE = os.getenv("MAIN_TENANTS_TABLE", "main.tenants")
36
- MAIN_TENANT_RESOURCE_ID_TABLE = os.getenv("MAIN_TENANT_RESOURCE_ID_TABLE", "main.tenant_resource_ids")
37
- MAIN_SUBSCRIPTIONS_TABLE = os.getenv("MAIN_SUBSCRIPTIONS_TABLE", "main.subscriptions")
38
- MAIN_APPS_TABLE = os.getenv("MAIN_APPS_TABLE", "main.apps")
39
- MAIN_USERS_TABLE = os.getenv("MAIN_USERS_TABLE", "main.users")
40
- MAIN_RESOURCE_TYPES_TABLE = os.getenv("MAIN_RESOURCE_TYPES_TABLE", "main.resource_types")
41
- MAIN_RESOURCE_ID_TABLE = os.getenv("MAIN_RESOURCE_ID_TABLE", "main.resource_ids")
42
- MAIN_RESOURCES_TABLE = os.getenv("MAIN_RESOURCES_TABLE", "main.resources")
43
- MAIN_PERMISSIONS_TABLE = os.getenv("MAIN_PERMISSIONS_TABLE", "main.permissions")
44
- MAIN_ROLES_TABLE = os.getenv("MAIN_ROLES_TABLE", "main.roles")
45
- MAIN_ROLE_PERMISSIONS_TABLE = os.getenv("MAIN_ROLE_PERMISSIONS_TABLE", "main.role_permissions")
46
- MAIN_USER_SUBSCRIPTIONS_TABLE = os.getenv("MAIN_USER_SUBSCRIPTIONS_TABLE", "main.user_subscriptions")
47
- MAIN_USER_SUBSCRIPTION_HISTORY_TABLE = os.getenv("MAIN_USER_SUBSCRIPTION_HISTORY_TABLE", "main.user_subscription_history")
48
- MAIN_OTP = os.getenv("MAIN_OTP", "main.otps")
49
- MAIN_PASSWORD_POLICY = os.getenv("MAIN_PASSWORD_POLICY", "main.password_policies")
50
- MAIN_MULTI_FACTOR_SETTINGS = os.getenv("MAIN_MULTI_FACTOR_SETTINGS", "main.multi_factor_settings")
51
- MAIN_USER_LOGIN_TRACKING = os.getenv("MAIN_USER_LOGIN_TRACKING", "main.user_login_tracking")
52
- MAIN_ENTERPRISE_SUBSCRIPTIONS_TABLE = os.getenv("MAIN_ENTERPRISE_SUBSCRIPTIONS_TABLE", "main.enterprise_subscriptions")
53
- MAIN_CHANGE_PASSWORD_POLICY_TABLE = os.getenv("MAIN_CHANGE_PASSWORD_POLICY_TABLE", "main.change_password_policy")
40
+ CORE_PLATFORM_TENANTS_TABLE = os.getenv("CORE_PLATFORM_TENANTS_TABLE", "core_platform.cp_tenants")
41
+ CORE_PLATFORM_TENANT_RESOURCE_ID_TABLE = os.getenv("CORE_PLATFORM_TENANT_RESOURCE_ID_TABLE", "core_platform.cp_resource_ids")
42
+ CORE_PLATFORM_SUBSCRIPTIONS_TABLE = os.getenv("CORE_PLATFORM_SUBSCRIPTIONS_TABLE", "core_platform.cp_subscriptions")
43
+ CORE_PLATFORM_APPS_TABLE = os.getenv("CORE_PLATFORM_APPS_TABLE", "core_platform.cp_apps")
44
+ CORE_PLATFORM_USERS_TABLE = os.getenv("CORE_PLATFORM_USERS_TABLE", "core_platform.cp_users")
45
+ CORE_PLATFORM_RESOURCE_TYPES_TABLE = os.getenv("CORE_PLATFORM_RESOURCE_TYPES_TABLE", "core_platform.cp_resource_types")
46
+ CORE_PLATFORM_RESOURCE_ID_TABLE = os.getenv("CORE_PLATFORM_RESOURCE_ID_TABLE", "core_platform.cp_shared_resource_ids")
47
+ CORE_PLATFORM_RESOURCES_TABLE = os.getenv("CORE_PLATFORM_RESOURCES_TABLE", "core_platform.resources")
48
+ CORE_PLATFORM_PERMISSIONS_TABLE = os.getenv("CORE_PLATFORM_PERMISSIONS_TABLE", "core_platform.cp_permissions")
49
+ CORE_PLATFORM_ROLES_TABLE = os.getenv("CORE_PLATFORM_ROLES_TABLE", "core_platform.cp_roles")
50
+ CORE_PLATFORM_ROLE_PERMISSIONS_TABLE = os.getenv("CORE_PLATFORM_ROLE_PERMISSIONS_TABLE", "core_platform.cp_role_permissions")
51
+ CORE_PLATFORM_USER_SUBSCRIPTIONS_TABLE = os.getenv("CORE_PLATFORM_USER_SUBSCRIPTIONS_TABLE", "core_platform.cp_user_subscriptions")
52
+ CORE_PLATFORM_USER_SUBSCRIPTION_HISTORY_TABLE = os.getenv("CORE_PLATFORM_USER_SUBSCRIPTION_HISTORY_TABLE", "core_platform.cp_user_subscription_histories")
53
+ CORE_PLATFORM_OTP = os.getenv("CORE_PLATFORM_OTP", "core_platform.cp_otps")
54
+ CORE_PLATFORM_PASSWORD_POLICY = os.getenv("CORE_PLATFORM_PASSWORD_POLICY", "core_platform.cp_password_policies")
55
+ CORE_PLATFORM_MULTI_FACTOR_SETTINGS = os.getenv("CORE_PLATFORM_MULTI_FACTOR_SETTINGS", "core_platform.cp_multi_factor_settings")
56
+ CORE_PLATFORM_USER_LOGIN_TRACKING = os.getenv("CORE_PLATFORM_USER_LOGIN_TRACKING", "core_platform.cp_user_login_tracking")
57
+ CORE_PLATFORM_ENTERPRISE_SUBSCRIPTIONS_TABLE = os.getenv("CORE_PLATFORM_ENTERPRISE_SUBSCRIPTIONS_TABLE", "core_platform.cp_enterprise_subscriptions")
58
+ CORE_PLATFORM_CHANGE_PASSWORD_POLICY_TABLE = os.getenv("CORE_PLATFORM_CHANGE_PASSWORD_POLICY_TABLE", "core_platform.cp_change_password_policy")
59
+ CORE_PLATFORM_APP_FEATURES_TABLE = os.getenv("CORE_PLATFORM_APP_FEATURES_TABLE", "core_platform.cp_app_features")
54
60
 
55
- # System-level tables
56
- MAIN_SYSTEM_GROUPS_TABLE = os.getenv("MAIN_SYSTEM_GROUPS_TABLE", "main.system_groups")
57
- MAIN_SYSTEM_USER_GROUPS_TABLE = os.getenv("MAIN_SYSTEM_USER_GROUPS_TABLE", "main.system_user_groups")
58
- MAIN_SYSTEM_ASSIGN_ROLES_TABLE = os.getenv("MAIN_SYSTEM_ASSIGN_ROLES_TABLE", "main.system_assign_roles")
59
-
60
61
  # =============================================================================
61
- # TENANT-SPECIFIC TABLES (tenant schemas)
62
+ # CORE PLATFORM TABLES (prefixed with cp_, now in core_platform schema with tenant_id)
63
+ # =============================================================================
64
+ # NOTE: These tables have been renamed from tenant_ prefix to cp_ (core platform).
65
+ # All tables include tenant_id column for multi-tenant isolation.
66
+ # Tables with is_system column can contain both user and system data.
62
67
  # =============================================================================
63
- TENANT_SUBSCRIPTIONS_TABLE = os.getenv("TENANT_SUBSCRIPTIONS_TABLE")
64
- TENANT_GROUPS_TABLE = os.getenv("TENANT_GROUPS_TABLE")
65
- TENANT_LOGIN_SETTINGS_TABLE = os.getenv("TENANT_LOGIN_SETTINGS_TABLE")
66
- TENANT_RESOURCES_TABLE = os.getenv("TENANT_RESOURCES_TABLE")
67
- TENANT_ASSIGN_ROLES_TABLE = os.getenv("TENANT_ASSIGN_ROLES_TABLE")
68
- TENANT_RESOURCE_ID_TABLE = os.getenv("TENANT_RESOURCE_ID_TABLE")
69
- TENANT_SUBSCRIPTION_HISTORY_TABLE = os.getenv("TENANT_SUBSCRIPTION_HISTORY_TABLE")
70
- TENANT_RESOURCE_DELETION_CHAT_HISTORY_TABLE = os.getenv("TENANT_RESOURCE_DELETION_CHAT_HISTORY_TABLE")
71
- TENANT_USER_GROUPS_TABLE = os.getenv("TENANT_USER_GROUPS_TABLE")
72
- TENANT_ACTIVITY_LOGS_TABLE = os.getenv("TENANT_ACTIVITY_LOGS_TABLE")
73
- TENANT_ORGANIZATIONS_TABLE = os.getenv("TENANT_ORGANIZATIONS_TABLE", "organizations")
74
- TENANT_BUSINESSES_TABLE = os.getenv("TENANT_BUSINESSES_TABLE", "businesses")
75
- TENANT_BUSINESS_APPS_TABLE = os.getenv("TENANT_BUSINESS_APPS_TABLE", "business_apps")
76
- TENANT_LOCATIONS_TABLE = os.getenv("TENANT_LOCATIONS_TABLE", "locations")
77
- TENANT_ASSIGN_LOCATIONS_TABLE = os.getenv("TENANT_ASSIGN_LOCATIONS_TABLE", "assign_locations")
78
- TENANT_UNIT_OF_MEASURE_TABLE = os.getenv("TENANT_UNIT_OF_MEASURE_TABLE")
79
- TENANT_CURRENCY=os.getenv("TENANT_CURRENCY")
68
+ CORE_PLATFORM_GROUPS_TABLE = os.getenv("CORE_PLATFORM_GROUPS_TABLE", "core_platform.cp_groups")
69
+ CORE_PLATFORM_LOGIN_SETTINGS_TABLE = os.getenv("CORE_PLATFORM_LOGIN_SETTINGS_TABLE", "core_platform.cp_login_settings")
70
+ CORE_PLATFORM_RESOURCES_TABLE = os.getenv("CORE_PLATFORM_RESOURCES_TABLE", "core_platform.cp_resources")
71
+ CORE_PLATFORM_ASSIGN_ROLES_TABLE = os.getenv("CORE_PLATFORM_ASSIGN_ROLES_TABLE", "core_platform.cp_assign_roles")
72
+ CORE_PLATFORM_RESOURCE_ID_TABLE = os.getenv("CORE_PLATFORM_RESOURCE_ID_TABLE", "core_platform.cp_resource_ids")
73
+ CORE_PLATFORM_SUBSCRIPTION_HISTORY_TABLE = os.getenv("CORE_PLATFORM_SUBSCRIPTION_HISTORY_TABLE", "core_platform.cp_user_subscription_histories")
74
+ CORE_PLATFORM_RESOURCE_DELETION_CHAT_HISTORY_TABLE = os.getenv("CORE_PLATFORM_RESOURCE_DELETION_CHAT_HISTORY_TABLE", "core_platform.cp_resource_deletion_chat_histories")
75
+ CORE_PLATFORM_USER_GROUPS_TABLE = os.getenv("CORE_PLATFORM_USER_GROUPS_TABLE", "core_platform.cp_user_groups")
76
+ CORE_PLATFORM_ACTIVITY_LOGS_TABLE = os.getenv("CORE_PLATFORM_ACTIVITY_LOGS_TABLE", "core_platform.cp_activity_logs")
77
+ CORE_PLATFORM_ORGANIZATIONS_TABLE = os.getenv("CORE_PLATFORM_ORGANIZATIONS_TABLE", "core_platform.cp_organizations")
78
+ CORE_PLATFORM_BUSINESSES_TABLE = os.getenv("CORE_PLATFORM_BUSINESSES_TABLE", "core_platform.cp_businesses")
79
+ CORE_PLATFORM_BUSINESS_APPS_TABLE = os.getenv("CORE_PLATFORM_BUSINESS_APPS_TABLE", "core_platform.cp_business_apps")
80
+ CORE_PLATFORM_LOCATIONS_TABLE = os.getenv("CORE_PLATFORM_LOCATIONS_TABLE", "core_platform.cp_locations")
81
+ CORE_PLATFORM_ASSIGN_LOCATIONS_TABLE = os.getenv("CORE_PLATFORM_ASSIGN_LOCATIONS_TABLE", "core_platform.cp_assign_locations")
82
+ CORE_PLATFORM_UNIT_OF_MEASURE_TABLE = os.getenv("CORE_PLATFORM_UNIT_OF_MEASURE_TABLE", "core_platform.cp_unit_of_measures")
83
+ CORE_PLATFORM_CURRENCY = os.getenv("CORE_PLATFORM_CURRENCY", "core_platform.cp_currencies")
80
84
 
81
85
  # Mail Configurations
82
86
  MAIL_SENDER_EMAIL=os.getenv("MAIL_SENDER_EMAIL")
@@ -96,14 +96,14 @@ class Helper:
96
96
 
97
97
  try:
98
98
  if tenant_id:
99
- # For tenant-specific resource IDs, check tenant schema
99
+ # For tenant-specific resource IDs, check shared schema with tenant_id filter
100
100
  # Note: TENANT_RESOURCE_ID_TABLE needs to be defined in settings
101
101
  tenant_resource_table = getattr(db_settings, 'TENANT_RESOURCE_ID_TABLE', None)
102
102
  if tenant_resource_table:
103
103
  resource_exists = DatabaseManager.execute_scalar(
104
- f"""SELECT COUNT(1) FROM "{tenant_id}".{tenant_resource_table}
105
- WHERE id = %s""",
106
- (candidate,),
104
+ f"""SELECT COUNT(1) FROM {tenant_resource_table}
105
+ WHERE tenant_id = %s AND id = %s""",
106
+ (tenant_id, candidate,),
107
107
  )
108
108
  else:
109
109
  # Fallback: assume no conflict if table not configured
@@ -263,12 +263,12 @@ class Helper:
263
263
  if user_id:
264
264
  try:
265
265
  logger.debug(f"Fetching user information for user_id={user_id}")
266
- main_users_table = getattr(db_settings, 'MAIN_USERS_TABLE', 'main.users')
266
+ main_users_table = getattr(db_settings, 'MAIN_USERS_TABLE', 'main.cp_users')
267
267
  user_data = DatabaseManager.execute_query(
268
268
  f"""SELECT email, contact, fullname
269
269
  FROM {main_users_table}
270
- WHERE id = %s""",
271
- (user_id,)
270
+ WHERE id = %s AND tenant_id = %s""",
271
+ (user_id, tenant_id)
272
272
  )
273
273
  logger.debug(f"User data query returned: {user_data}")
274
274
 
@@ -289,10 +289,10 @@ class Helper:
289
289
  logger.debug(f"Activity log values - performed_by_email: {performed_by_email}, performed_by_contact: {performed_by_contact}, performed_by_fullname: {performed_by_fullname}")
290
290
 
291
291
  result = DatabaseManager.execute_update(
292
- f"""INSERT INTO "{tenant_id}".{tenant_activity_logs_table}
293
- (id, action, resource_type, old_data, new_data, description, performed_by_email, performed_by_contact, performed_by_fullname, cdate, ctime, cdatetime)
294
- VALUES (%s, %s, NULLIF(%s, '')::text, %s::jsonb, %s::jsonb, %s, %s, %s, %s, %s, %s, %s)""",
295
- (log_id, action, resource_type, old_json, new_json, description, performed_by_email, performed_by_contact, performed_by_fullname, cdate, ctime, cdatetime),
292
+ f"""INSERT INTO {tenant_activity_logs_table}
293
+ (id, tenant_id, action, resource_type, old_data, new_data, description, performed_by_email, performed_by_contact, performed_by_fullname, cdate, ctime, cdatetime)
294
+ VALUES (%s, %s, %s, NULLIF(%s, '')::text, %s::jsonb, %s::jsonb, %s, %s, %s, %s, %s, %s, %s)""",
295
+ (log_id, tenant_id, action, resource_type, old_json, new_json, description, performed_by_email, performed_by_contact, performed_by_fullname, cdate, ctime, cdatetime),
296
296
  )
297
297
 
298
298
  logger.info(f"Activity logged successfully. Rows affected: {result}")
@@ -301,9 +301,9 @@ class Helper:
301
301
  if result > 0:
302
302
  verify_data = DatabaseManager.execute_query(
303
303
  f"""SELECT performed_by_email, performed_by_contact, performed_by_fullname
304
- FROM "{tenant_id}".{tenant_activity_logs_table}
305
- WHERE id = %s""",
306
- (log_id,)
304
+ FROM {tenant_activity_logs_table}
305
+ WHERE tenant_id = %s AND id = %s""",
306
+ (tenant_id, log_id,)
307
307
  )
308
308
  if verify_data:
309
309
  logger.debug(f"Verification - Inserted activity log data: {verify_data[0]}")
@@ -416,23 +416,25 @@ class Helper:
416
416
  # Get table names from settings with fallbacks
417
417
  main_users_table = getattr(db_settings, 'MAIN_USERS_TABLE', 'main.users')
418
418
  main_roles_table = getattr(db_settings, 'MAIN_ROLES_TABLE', 'main.roles')
419
- tenant_assign_roles_table = getattr(db_settings, 'TENANT_ASSIGN_ROLES_TABLE', 'assign_roles')
420
- tenant_user_groups_table = getattr(db_settings, 'TENANT_USER_GROUPS_TABLE', 'user_groups')
419
+ tenant_assign_roles_table = getattr(db_settings, 'TENANT_ASSIGN_ROLES_TABLE', 'main.tenant_assign_roles')
420
+ tenant_user_groups_table = getattr(db_settings, 'TENANT_USER_GROUPS_TABLE', 'main.tenant_user_groups')
421
421
 
422
422
  # Query to get users with admin roles - both direct and through groups
423
423
  query = f"""
424
424
  SELECT DISTINCT u.id as user_id, u.email, u.fullname
425
425
  FROM {main_users_table} u
426
- WHERE u.delete_status = 'NOT_DELETED'
426
+ WHERE u.tenant_id = %s
427
+ AND u.delete_status = 'NOT_DELETED'
427
428
  AND u.is_active = true
428
429
  AND u.can_login = true
429
430
  AND (
430
431
  -- Direct role assignment
431
- u.id IN (
432
- SELECT ar.user_id
433
- FROM "{tenant_id}".{tenant_assign_roles_table} ar
434
- INNER JOIN {main_roles_table} r ON ar.role_id = r.id
435
- WHERE ar.delete_status = 'NOT_DELETED'
432
+ (u.id, u.tenant_id) IN (
433
+ SELECT ar.user_id, ar.tenant_id
434
+ FROM {tenant_assign_roles_table} ar
435
+ INNER JOIN {main_roles_table} r ON ar.role_id = r.id AND ar.tenant_id = r.tenant_id
436
+ WHERE ar.tenant_id = %s
437
+ AND ar.delete_status = 'NOT_DELETED'
436
438
  AND ar.is_active = true
437
439
  AND r.delete_status = 'NOT_DELETED'
438
440
  AND r.is_active = true
@@ -441,12 +443,14 @@ class Helper:
441
443
  )
442
444
  OR
443
445
  -- Group-based role assignment
444
- u.id IN (
445
- SELECT ug.user_id
446
- FROM "{tenant_id}".{tenant_user_groups_table} ug
447
- INNER JOIN "{tenant_id}".{tenant_assign_roles_table} ar ON ug.group_id = ar.group_id
448
- INNER JOIN {main_roles_table} r ON ar.role_id = r.id
449
- WHERE ug.delete_status = 'NOT_DELETED'
446
+ (u.id, u.tenant_id) IN (
447
+ SELECT ug.user_id, ug.tenant_id
448
+ FROM {tenant_user_groups_table} ug
449
+ INNER JOIN {tenant_assign_roles_table} ar ON ug.group_id = ar.group_id AND ug.tenant_id = ar.tenant_id
450
+ INNER JOIN {main_roles_table} r ON ar.role_id = r.id AND ar.tenant_id = r.tenant_id
451
+ WHERE ug.tenant_id = %s
452
+ AND ar.tenant_id = %s
453
+ AND ug.delete_status = 'NOT_DELETED'
450
454
  AND ug.is_active = true
451
455
  AND ar.delete_status = 'NOT_DELETED'
452
456
  AND ar.is_active = true
@@ -458,7 +462,7 @@ class Helper:
458
462
  )
459
463
  """
460
464
 
461
- results = DatabaseManager.execute_query(query)
465
+ results = DatabaseManager.execute_query(query, (tenant_id, tenant_id, tenant_id, tenant_id,))
462
466
 
463
467
  admin_users = []
464
468
  if results:
@@ -564,15 +568,15 @@ class Helper:
564
568
  actor_email = "no-reply@trovesuite.com"
565
569
 
566
570
  if actor_user_id:
567
- main_users_table = getattr(db_settings, 'MAIN_USERS_TABLE', 'main.users')
571
+ main_users_table = getattr(db_settings, 'MAIN_USERS_TABLE', 'main.cp_users')
568
572
  actor_details = DatabaseManager.execute_query(
569
573
  f"""SELECT fullname, email
570
574
  FROM {main_users_table}
571
- WHERE id = %s""",
572
- (actor_user_id,),
575
+ WHERE id = %s AND tenant_id = %s""",
576
+ (actor_user_id, tenant_id),
573
577
  )
574
578
 
575
- if actor_details:
579
+ if actor_details and len(actor_details) > 0:
576
580
  actor_data = dict(actor_details[0])
577
581
  actor_name_candidate = (actor_data.get("fullname") or "").strip()
578
582
  actor_name = actor_name_candidate or actor_data.get("email") or actor_name
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: trovesuite
3
- Version: 1.0.17
3
+ Version: 1.0.19
4
4
  Summary: TroveSuite services package providing authentication, authorization, notifications, Azure Storage, and other enterprise services for TroveSuite applications
5
5
  Home-page: https://dev.azure.com/brightgclt/trovesuite/_git/packages
6
6
  Author: Bright Debrah Owusu
@@ -3,12 +3,12 @@ trovesuite/auth/__init__.py,sha256=OjZllVvjul1glDazJ-d5TrNjgHFigFlQQi1G99DYshk,2
3
3
  trovesuite/auth/auth_base.py,sha256=rZHQVLeJRBQ8GClgF5UwG-er4_HXVX5-nt8o6_Z29uY,75
4
4
  trovesuite/auth/auth_controller.py,sha256=PAgaVlf5TYEfkSfK4vGGsvO84i8zEmeVVXyUF2YBppI,420
5
5
  trovesuite/auth/auth_read_dto.py,sha256=e27JqKVPVUM83A_mYF452QCflsvGNo7aKje7q_urwFc,571
6
- trovesuite/auth/auth_service.py,sha256=G2_lkXdMnuqpBjKFYGlRUrUvVyq8keukXaSyboiWiUM,18106
6
+ trovesuite/auth/auth_service.py,sha256=LVFGM1e6AobQbY62nXQE_clFqC-Q0Li8fNMP6Hm_jtM,19723
7
7
  trovesuite/auth/auth_write_dto.py,sha256=rdwI7w6-9QZGv1H0PAGrjkLBCzaMHjgPIXeLb9RmNec,234
8
8
  trovesuite/configs/__init__.py,sha256=h1mSZOaZ3kUy1ZMO_m9O9KklsxywM0RfMVZLh9h9WvQ,328
9
9
  trovesuite/configs/database.py,sha256=IPSu8fXjxyYeJ3bFknJG06Qm2L2ub6Ht19xhKv8g7nA,11731
10
10
  trovesuite/configs/logging.py,sha256=mGjR2d4urVNry9l5_aXycMMtcY2RAFIpEL35hw33KZg,9308
11
- trovesuite/configs/settings.py,sha256=9kl4f7AOtulUnmoWcrLVa8LKjGirZkPYSWtACoTqr5U,5652
11
+ trovesuite/configs/settings.py,sha256=2S1zPHJiYWaK6xT-tnZBfT2gJ-C0O6qXMtVQt_Xtyi4,7200
12
12
  trovesuite/entities/__init__.py,sha256=Dbl_03Bueyh2vOP2hykd40MmNMrl5nNHSRGP-kqwwNo,160
13
13
  trovesuite/entities/health.py,sha256=KaW7yxTQdymIPlnkJJkDqEebBXkD0a7A66i5GgNZLoE,2700
14
14
  trovesuite/entities/sh_response.py,sha256=1_sw3PpVaDxWsNiBU0W9YLHZgTFxEj4JJBLBfSY63Ho,1579
@@ -25,10 +25,10 @@ trovesuite/storage/storage_read_dto.py,sha256=o7EVJdwrwVZAaeyGU9O01WMECGVaytkvLR
25
25
  trovesuite/storage/storage_service.py,sha256=V7LIePIV6b_iuhm-9x8r4zwpZHgeRPL1YIe5IBnxhco,19768
26
26
  trovesuite/storage/storage_write_dto.py,sha256=vl1iCZ93bpFmpvkCrn587QtMtOA_TPDseXSoTuj9RTQ,1355
27
27
  trovesuite/utils/__init__.py,sha256=mDZuY77BphvQFYLmcWxjP5Tcq9ZZ3WXJWBKB1v6wzHU,185
28
- trovesuite/utils/helper.py,sha256=k7Meg8sN4aPBdqcjaF1tQcZ32KvuA-IqjpWniQP_Mpk,26438
28
+ trovesuite/utils/helper.py,sha256=NySt18kl4Dc78tN5HiB7SpsCH5DWy3QvG1AMtl-ASBM,26951
29
29
  trovesuite/utils/templates.py,sha256=_92k4-EkqWs-h0LNJxPgorbspmp24kDngS7O3qWIFyQ,20388
30
- trovesuite-1.0.17.dist-info/licenses/LICENSE,sha256=EJT35ct-Q794JYPdAQy3XNczQGKkU1HzToLeK1YVw2s,1070
31
- trovesuite-1.0.17.dist-info/METADATA,sha256=UB2VoJbb7XXl1GUPVjq8BL_zXB_DMQMzSmuYabHBuAo,21737
32
- trovesuite-1.0.17.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
33
- trovesuite-1.0.17.dist-info/top_level.txt,sha256=GzKhG_-MTaxeHrIgkGkBH_nof2vroGFBrjeHKWUIwNc,11
34
- trovesuite-1.0.17.dist-info/RECORD,,
30
+ trovesuite-1.0.19.dist-info/licenses/LICENSE,sha256=EJT35ct-Q794JYPdAQy3XNczQGKkU1HzToLeK1YVw2s,1070
31
+ trovesuite-1.0.19.dist-info/METADATA,sha256=0h1PBqKcvc3fjKvXFgKepDCLnfNea1jdVJZphYPGyu4,21737
32
+ trovesuite-1.0.19.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
33
+ trovesuite-1.0.19.dist-info/top_level.txt,sha256=GzKhG_-MTaxeHrIgkGkBH_nof2vroGFBrjeHKWUIwNc,11
34
+ trovesuite-1.0.19.dist-info/RECORD,,