trovesuite 1.0.26__tar.gz → 1.0.27__tar.gz

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.
Files changed (43) hide show
  1. {trovesuite-1.0.26/src/trovesuite.egg-info → trovesuite-1.0.27}/PKG-INFO +1 -1
  2. {trovesuite-1.0.26 → trovesuite-1.0.27}/pyproject.toml +2 -2
  3. {trovesuite-1.0.26 → trovesuite-1.0.27}/setup.py +1 -1
  4. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite/configs/settings.py +1 -0
  5. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite/utils/helper.py +94 -5
  6. {trovesuite-1.0.26 → trovesuite-1.0.27/src/trovesuite.egg-info}/PKG-INFO +1 -1
  7. {trovesuite-1.0.26 → trovesuite-1.0.27}/LICENSE +0 -0
  8. {trovesuite-1.0.26 → trovesuite-1.0.27}/MANIFEST.in +0 -0
  9. {trovesuite-1.0.26 → trovesuite-1.0.27}/README.md +0 -0
  10. {trovesuite-1.0.26 → trovesuite-1.0.27}/requirements.txt +0 -0
  11. {trovesuite-1.0.26 → trovesuite-1.0.27}/setup.cfg +0 -0
  12. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite/__init__.py +0 -0
  13. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite/auth/__init__.py +0 -0
  14. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite/auth/auth_base.py +0 -0
  15. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite/auth/auth_controller.py +0 -0
  16. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite/auth/auth_read_dto.py +0 -0
  17. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite/auth/auth_service.py +0 -0
  18. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite/auth/auth_write_dto.py +0 -0
  19. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite/configs/__init__.py +0 -0
  20. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite/configs/database.py +0 -0
  21. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite/configs/logging.py +0 -0
  22. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite/entities/__init__.py +0 -0
  23. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite/entities/health.py +0 -0
  24. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite/entities/sh_response.py +0 -0
  25. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite/notification/__init__.py +0 -0
  26. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite/notification/notification_base.py +0 -0
  27. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite/notification/notification_controller.py +0 -0
  28. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite/notification/notification_read_dto.py +0 -0
  29. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite/notification/notification_service.py +0 -0
  30. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite/notification/notification_write_dto.py +0 -0
  31. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite/storage/__init__.py +0 -0
  32. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite/storage/storage_base.py +0 -0
  33. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite/storage/storage_controller.py +0 -0
  34. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite/storage/storage_read_dto.py +0 -0
  35. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite/storage/storage_service.py +0 -0
  36. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite/storage/storage_write_dto.py +0 -0
  37. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite/utils/__init__.py +0 -0
  38. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite/utils/templates.py +0 -0
  39. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite.egg-info/SOURCES.txt +0 -0
  40. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite.egg-info/dependency_links.txt +0 -0
  41. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite.egg-info/not-zip-safe +0 -0
  42. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite.egg-info/requires.txt +0 -0
  43. {trovesuite-1.0.26 → trovesuite-1.0.27}/src/trovesuite.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: trovesuite
3
- Version: 1.0.26
3
+ Version: 1.0.27
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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [tool.poetry]
6
6
  name = "trovesuite"
7
- version = "1.0.26"
7
+ version = "1.0.27"
8
8
  description = "TroveSuite services package providing authentication, authorization, notifications, Azure Storage, and other enterprise services for TroveSuite applications"
9
9
  authors = ["brightgclt <brightgclt@gmail.com>"]
10
10
  license = "MIT"
@@ -58,7 +58,7 @@ Documentation = "https://dev.azure.com/brightgclt/trovesuite/_git/packages"
58
58
 
59
59
  [project]
60
60
  name = "trovesuite"
61
- version = "1.0.26"
61
+ version = "1.0.27"
62
62
  description = "TroveSuite services package providing authentication, authorization, notifications, Azure Storage, and other enterprise services for TroveSuite applications"
63
63
  readme = "README.md"
64
64
  license = {text = "MIT"}
@@ -15,7 +15,7 @@ with open("pyproject.toml", "r", encoding="utf-8") as fh:
15
15
 
16
16
  setup(
17
17
  name="trovesuite",
18
- version="1.0.26",
18
+ version="1.0.27",
19
19
  author="Bright Debrah Owusu",
20
20
  author_email="owusu.debrah@deladetech.com",
21
21
  description="TroveSuite services package providing authentication, authorization, notifications, and other enterprise services for TroveSuite applications",
@@ -79,6 +79,7 @@ class Settings:
79
79
  CORE_PLATFORM_UNIT_OF_MEASURE_TABLE = os.getenv("CORE_PLATFORM_UNIT_OF_MEASURE_TABLE", "core_platform.cp_unit_of_measures")
80
80
  CORE_PLATFORM_CURRENCY = os.getenv("CORE_PLATFORM_CURRENCY", "core_platform.cp_currencies")
81
81
  CORE_PLATFORM_THEMES_TABLE = os.getenv("CORE_PLATFORM_THEMES_TABLE", "core_platform.cp_themes")
82
+ CORE_PLATFORM_NOTIFICATION_EMAIL_CREDENTIALS_TABLE = os.getenv("CORE_PLATFORM_NOTIFICATION_EMAIL_CREDENTIALS_TABLE", "core_platform.cp_notification_email_credentials")
82
83
 
83
84
  # Mail Configurations
84
85
  MAIL_SENDER_EMAIL=os.getenv("MAIL_SENDER_EMAIL")
@@ -314,6 +314,75 @@ class Helper:
314
314
  # Log the error but don't fail the main operation
315
315
  logger.error(f"Failed to log activity: {str(e)}", exc_info=True)
316
316
 
317
+ @staticmethod
318
+ def get_email_credentials(tenant_id: Optional[str] = None) -> tuple[Optional[str], Optional[str]]:
319
+ """
320
+ Get email credentials for sending notifications.
321
+ If tenant_id is provided and tenant has custom email credentials, use those.
322
+ Otherwise, fall back to system default credentials.
323
+
324
+ Args:
325
+ tenant_id: Optional tenant ID to check for tenant-specific credentials
326
+
327
+ Returns:
328
+ Tuple of (email, password) or (None, None) if not configured
329
+ """
330
+ # If tenant_id is provided, check for tenant-specific credentials
331
+ if tenant_id:
332
+ try:
333
+ credentials_table = getattr(db_settings, 'CORE_PLATFORM_NOTIFICATION_EMAIL_CREDENTIALS_TABLE', 'core_platform.cp_notification_email_credentials')
334
+ tenant_credentials = DatabaseManager.execute_query(
335
+ f"""SELECT notification_email, notification_password
336
+ FROM {credentials_table}
337
+ WHERE tenant_id = %s
338
+ AND delete_status = 'NOT_DELETED'
339
+ AND is_active = true""",
340
+ (tenant_id,),
341
+ )
342
+
343
+ if tenant_credentials and len(tenant_credentials) > 0:
344
+ tenant_email = tenant_credentials[0].get('notification_email')
345
+ tenant_password = tenant_credentials[0].get('notification_password')
346
+
347
+ # If tenant has both email and password configured, use them
348
+ if tenant_email and tenant_password:
349
+ logger.info(
350
+ f"Using tenant-specific email credentials for tenant {tenant_id}",
351
+ extra={
352
+ "extra_fields": {
353
+ "tenant_id": tenant_id,
354
+ "email": tenant_email
355
+ }
356
+ }
357
+ )
358
+ return (tenant_email, tenant_password)
359
+ except Exception as e:
360
+ logger.warning(
361
+ f"Error fetching tenant email credentials for tenant {tenant_id}: {str(e)}",
362
+ extra={
363
+ "extra_fields": {
364
+ "tenant_id": tenant_id,
365
+ "error": str(e)
366
+ }
367
+ }
368
+ )
369
+
370
+ # Fall back to system default credentials
371
+ mail_sender_email = getattr(db_settings, 'MAIL_SENDER_EMAIL', None)
372
+ mail_sender_pwd = getattr(db_settings, 'MAIL_SENDER_PWD', None)
373
+
374
+ if tenant_id:
375
+ logger.info(
376
+ f"Using system default email credentials for tenant {tenant_id}",
377
+ extra={
378
+ "extra_fields": {
379
+ "tenant_id": tenant_id
380
+ }
381
+ }
382
+ )
383
+
384
+ return (mail_sender_email, mail_sender_pwd)
385
+
317
386
  @staticmethod
318
387
  def send_notification(
319
388
  email: str,
@@ -321,8 +390,19 @@ class Helper:
321
390
  text_template: str,
322
391
  html_template: str,
323
392
  variables: Optional[Dict[str, str]] = None,
393
+ tenant_id: Optional[str] = None,
324
394
  ):
325
- """Send a dynamic notification email."""
395
+ """
396
+ Send a dynamic notification email.
397
+
398
+ Args:
399
+ email: Recipient email address
400
+ subject: Email subject
401
+ text_template: Plain text email template
402
+ html_template: HTML email template
403
+ variables: Optional dictionary of variables to format templates
404
+ tenant_id: Optional tenant ID to use tenant-specific email credentials
405
+ """
326
406
  current_time = Helper.current_date_time()
327
407
  cdate = current_time["cdate"]
328
408
  ctime = current_time["ctime"]
@@ -345,12 +425,19 @@ class Helper:
345
425
  text_message = text_template.format(**safe_variables)
346
426
  html_message = html_template.format(**safe_variables)
347
427
 
348
- # Build email data
349
- mail_sender_email = getattr(db_settings, 'MAIL_SENDER_EMAIL', None)
350
- mail_sender_pwd = getattr(db_settings, 'MAIL_SENDER_PWD', None)
428
+ # Get email credentials (tenant-specific or system default)
429
+ mail_sender_email, mail_sender_pwd = Helper.get_email_credentials(tenant_id)
351
430
 
352
431
  if not mail_sender_email or not mail_sender_pwd:
353
- logger.error("MAIL_SENDER_EMAIL or MAIL_SENDER_PWD not configured in settings")
432
+ logger.error(
433
+ "Email credentials not configured. MAIL_SENDER_EMAIL or MAIL_SENDER_PWD not set in settings",
434
+ extra={
435
+ "extra_fields": {
436
+ "tenant_id": tenant_id,
437
+ "receiver_email": email
438
+ }
439
+ }
440
+ )
354
441
  return
355
442
 
356
443
  notification_data = NotificationEmailServiceWriteDto(
@@ -620,6 +707,8 @@ class Helper:
620
707
  "status_color": config["color"],
621
708
  "status_icon": config["icon"],
622
709
  "actor_name": actor_name,
710
+ },
711
+ tenant_id=tenant_id,
623
712
  "actor_email": actor_email,
624
713
  "message": message_value,
625
714
  "message_text": message_text,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: trovesuite
3
- Version: 1.0.26
3
+ Version: 1.0.27
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
File without changes
File without changes
File without changes
File without changes