io4it 2.1.7__tar.gz → 2.1.7.1__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.
- {io4it-2.1.7 → io4it-2.1.7.1}/PKG-INFO +1 -1
- {io4it-2.1.7 → io4it-2.1.7.1}/io4it.egg-info/PKG-INFO +1 -1
- {io4it-2.1.7 → io4it-2.1.7.1}/io4it.egg-info/SOURCES.txt +5 -4
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/utils/mail.py +326 -3
- io4it-2.1.7.1/orangecontrib/IO4IT/utils/secret_manager.py +300 -0
- io4it-2.1.7/orangecontrib/IO4IT/widgets/OWDoclingMarkdownizerSimple.py → io4it-2.1.7.1/orangecontrib/IO4IT/widgets/OWDoclingToMarkdown.py +3 -3
- io4it-2.1.7/orangecontrib/IO4IT/widgets/OWExtractTablesDocxToCSV.py → io4it-2.1.7.1/orangecontrib/IO4IT/widgets/OWExtractTablesDocxToXlsx.py +121 -30
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/OWInboxMailMonitoring.py +2 -1
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/OWS3Uploader.py +3 -3
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/OWmailSender.py +2 -2
- io4it-2.1.7/orangecontrib/IO4IT/widgets/designer/owdocxtocsv.ui → io4it-2.1.7.1/orangecontrib/IO4IT/widgets/designer/owdocxtoxlsx.ui +37 -9
- {io4it-2.1.7 → io4it-2.1.7.1}/setup.py +1 -1
- {io4it-2.1.7 → io4it-2.1.7.1}/io4it.egg-info/dependency_links.txt +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/io4it.egg-info/entry_points.txt +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/io4it.egg-info/namespace_packages.txt +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/io4it.egg-info/requires.txt +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/io4it.egg-info/top_level.txt +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/__init__.py +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/ocr_function/__init__.py +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/ocr_function/word_converter.py +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/utils/__init__.py +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/utils/offuscation_basique.py +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/utils/pool_exec_utils.py +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/utils/utils_md.py +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/OWChatGpt.py +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/OWDeep_Search.py +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/OWExportMarkdown.py +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/OWMarkdownLoader.py +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/OWMarkdownizer.py +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/OWOfficeNormalizer.py +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/OWPdfType.py +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/OWProcessPoolExecutor.py +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/OWS3downloader.py +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/OWS3list.py +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/OWSpeechToText.py +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/OWmailLoader.py +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/OWwordpdf2docx.py +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/__init__.py +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/designer/__init__.py +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/designer/nogui.ui +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/designer/ow_file_ext_selector.ui +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/designer/owchatgpt.ui +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/designer/owdeepsearch.ui +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/designer/owdoclingasr.ui +0 -0
- /io4it-2.1.7/orangecontrib/IO4IT/widgets/designer/owdoclingmarkdownizersimple.ui → /io4it-2.1.7.1/orangecontrib/IO4IT/widgets/designer/owdoclingtomarkdown.ui +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/designer/owexportmarkdown.ui +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/designer/owinboxmailmonitoring.ui +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/designer/owmailloader.ui +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/designer/owmailsender.ui +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/designer/owmarkdownizer.ui +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/designer/owmarkdownloader.ui +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/designer/owofficenormalizer.ui +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/designer/owpdftype.ui +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/designer/owprocesspoolexecutor.ui +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/designer/owspeechtotext.ui +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/designer/owvisualizationer.ui +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/designer/wordpdf2docx.ui +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/icons/__init__.py +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/icons/chatgpt.png +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/icons/check_pdf.png +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/icons/deepsearch.svg +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/icons/dep_md_old.png +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/icons/download.png +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/icons/export_md.png +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/icons/extract_table.png +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/icons/file_extensor.png +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/icons/list_aws.png +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/icons/load_md.png +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/icons/mail_loader.png +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/icons/mail_writer.png +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/icons/md.png +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/icons/monitor-email.svg +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/icons/office_normalizer.png +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/icons/process_pool_executor.png +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/icons/speech_to_text.png +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/icons/upload.png +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/icons/visualizationer.png +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/icons/wordpdf2docx.png +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/IO4IT/widgets/icons_dev/__init__.py +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/orangecontrib/__init__.py +0 -0
- {io4it-2.1.7 → io4it-2.1.7.1}/setup.cfg +0 -0
|
@@ -14,12 +14,13 @@ orangecontrib/IO4IT/utils/__init__.py
|
|
|
14
14
|
orangecontrib/IO4IT/utils/mail.py
|
|
15
15
|
orangecontrib/IO4IT/utils/offuscation_basique.py
|
|
16
16
|
orangecontrib/IO4IT/utils/pool_exec_utils.py
|
|
17
|
+
orangecontrib/IO4IT/utils/secret_manager.py
|
|
17
18
|
orangecontrib/IO4IT/utils/utils_md.py
|
|
18
19
|
orangecontrib/IO4IT/widgets/OWChatGpt.py
|
|
19
20
|
orangecontrib/IO4IT/widgets/OWDeep_Search.py
|
|
20
|
-
orangecontrib/IO4IT/widgets/
|
|
21
|
+
orangecontrib/IO4IT/widgets/OWDoclingToMarkdown.py
|
|
21
22
|
orangecontrib/IO4IT/widgets/OWExportMarkdown.py
|
|
22
|
-
orangecontrib/IO4IT/widgets/
|
|
23
|
+
orangecontrib/IO4IT/widgets/OWExtractTablesDocxToXlsx.py
|
|
23
24
|
orangecontrib/IO4IT/widgets/OWInboxMailMonitoring.py
|
|
24
25
|
orangecontrib/IO4IT/widgets/OWMarkdownLoader.py
|
|
25
26
|
orangecontrib/IO4IT/widgets/OWMarkdownizer.py
|
|
@@ -40,8 +41,8 @@ orangecontrib/IO4IT/widgets/designer/ow_file_ext_selector.ui
|
|
|
40
41
|
orangecontrib/IO4IT/widgets/designer/owchatgpt.ui
|
|
41
42
|
orangecontrib/IO4IT/widgets/designer/owdeepsearch.ui
|
|
42
43
|
orangecontrib/IO4IT/widgets/designer/owdoclingasr.ui
|
|
43
|
-
orangecontrib/IO4IT/widgets/designer/
|
|
44
|
-
orangecontrib/IO4IT/widgets/designer/
|
|
44
|
+
orangecontrib/IO4IT/widgets/designer/owdoclingtomarkdown.ui
|
|
45
|
+
orangecontrib/IO4IT/widgets/designer/owdocxtoxlsx.ui
|
|
45
46
|
orangecontrib/IO4IT/widgets/designer/owexportmarkdown.ui
|
|
46
47
|
orangecontrib/IO4IT/widgets/designer/owinboxmailmonitoring.ui
|
|
47
48
|
orangecontrib/IO4IT/widgets/designer/owmailloader.ui
|
|
@@ -11,8 +11,8 @@ import mimetypes
|
|
|
11
11
|
from exchangelib import Credentials, HTMLBody, Message, Mailbox
|
|
12
12
|
#from exchangelib.protocol import BaseProtocol, NoVerifyHTTPAdapter
|
|
13
13
|
from exchangelib import OAuth2Credentials, Identity, Configuration, Account, DELEGATE
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
import requests
|
|
15
|
+
import base64
|
|
16
16
|
from bs4 import BeautifulSoup
|
|
17
17
|
|
|
18
18
|
|
|
@@ -431,10 +431,202 @@ def check_new_emails(offusc_conf_agent,type_co, list_agent_email=[]):
|
|
|
431
431
|
f.write("\n".join(output_lines))
|
|
432
432
|
with open(os.path.join(folder, "mail.ok"), "w") as f:
|
|
433
433
|
pass
|
|
434
|
+
except Exception as e:
|
|
435
|
+
print(f"Erreur OAuth2 lors du traitement du mail : {e}")
|
|
436
|
+
|
|
437
|
+
elif type_co == "MICROSOFT_EXCHANGE_OAUTH2_MICROSOFT_GRAPH":
|
|
438
|
+
try:
|
|
439
|
+
print("🔍 [DEBUG] Début de la vérification des emails avec Microsoft Graph OAuth2")
|
|
440
|
+
client_id, client_secret, tenant_id, user_email = offuscation_basique.lire_config_cli_oauth2(
|
|
441
|
+
offusc_conf_agent)
|
|
442
|
+
print(f"🔍 [DEBUG] Configuration lue - User: {user_email}, Tenant: {tenant_id}")
|
|
443
|
+
|
|
444
|
+
authority = f"https://login.microsoftonline.com/{tenant_id}"
|
|
445
|
+
|
|
446
|
+
app = ConfidentialClientApplication(
|
|
447
|
+
client_id=client_id,
|
|
448
|
+
client_credential=client_secret,
|
|
449
|
+
authority=authority
|
|
450
|
+
)
|
|
451
|
+
print("🔍 [DEBUG] Application MSAL créée")
|
|
452
|
+
|
|
453
|
+
# Essayer d'abord avec les permissions d'application (Client Credentials)
|
|
454
|
+
token_result = app.acquire_token_for_client(scopes=["https://graph.microsoft.com/.default"])
|
|
455
|
+
if "access_token" not in token_result:
|
|
456
|
+
raise Exception("Impossible d'obtenir un token : ", token_result.get("error_description"))
|
|
457
|
+
|
|
458
|
+
print("🔍 [DEBUG] Token d'accès obtenu avec succès (Client Credentials)")
|
|
459
|
+
access_token = token_result['access_token']
|
|
460
|
+
headers = {
|
|
461
|
+
'Authorization': f'Bearer {access_token}',
|
|
462
|
+
'Content-Type': 'application/json'
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
# Récupérer les emails non lus
|
|
466
|
+
graph_url = f"https://graph.microsoft.com/v1.0/users/{user_email}/messages"
|
|
467
|
+
params = {
|
|
468
|
+
'$filter': 'isRead eq false',
|
|
469
|
+
'$orderby': 'receivedDateTime asc',
|
|
470
|
+
'$select': 'id,subject,sender,toRecipients,ccRecipients,receivedDateTime,body,hasAttachments'
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
print(f"🔍 [DEBUG] Requête Graph API: {graph_url}")
|
|
474
|
+
print(f"🔍 [DEBUG] Paramètres: {params}")
|
|
475
|
+
|
|
476
|
+
try:
|
|
477
|
+
response = requests.get(graph_url, headers=headers, params=params)
|
|
478
|
+
response.raise_for_status()
|
|
479
|
+
emails_data = response.json()
|
|
480
|
+
print(
|
|
481
|
+
f"🔍 [DEBUG] Réponse Graph API reçue - Nombre d'emails non lus: {len(emails_data.get('value', []))}")
|
|
482
|
+
except requests.exceptions.HTTPError as e:
|
|
483
|
+
if response.status_code == 403:
|
|
484
|
+
print("🔍 [DEBUG] Erreur 403 - Permissions insuffisantes")
|
|
485
|
+
print("🔍 [DEBUG] ==============================================")
|
|
486
|
+
print("🔍 [DEBUG] ACTION REQUISE - Contactez votre IT Admin:")
|
|
487
|
+
print("🔍 [DEBUG] ==============================================")
|
|
488
|
+
print("🔍 [DEBUG] Votre application Azure AD manque des permissions.")
|
|
489
|
+
print("🔍 [DEBUG] App: IA-ODATAMINING")
|
|
490
|
+
print("🔍 [DEBUG] ID: 30ae55f5-f41e-4d44-afcc-082e4b803ba1")
|
|
491
|
+
print("🔍 [DEBUG] Tenant: 9988c2b8-3feb-4426-aeb7-b8d695bcd025")
|
|
492
|
+
print("🔍 [DEBUG] ")
|
|
493
|
+
print("🔍 [DEBUG] Permissions manquantes (Application type):")
|
|
494
|
+
print("🔍 [DEBUG] - Mail.Read - pour lire les emails")
|
|
495
|
+
print("🔍 [DEBUG] - Mail.Send - pour envoyer des emails")
|
|
496
|
+
print("🔍 [DEBUG] ")
|
|
497
|
+
print("🔍 [DEBUG] INFORMATIONS POUR VOTRE IT ADMIN:")
|
|
498
|
+
print("🔍 [DEBUG] 1. Azure Portal → Azure AD → App registrations")
|
|
499
|
+
print("🔍 [DEBUG] 2. Trouver l'app: IA-ODATAMINING")
|
|
500
|
+
print("🔍 [DEBUG] 3. API permissions → Add permission → Microsoft Graph")
|
|
501
|
+
print("🔍 [DEBUG] 4. Application permissions → Mail.Read + Mail.Send")
|
|
502
|
+
print("🔍 [DEBUG] 5. Grant admin consent")
|
|
503
|
+
print("🔍 [DEBUG] ")
|
|
504
|
+
print("🔍 [DEBUG] URL de consentement admin:")
|
|
505
|
+
print(f"🔍 [DEBUG] https://login.microsoftonline.com/{tenant_id}/adminconsent?client_id={client_id}")
|
|
506
|
+
print("🔍 [DEBUG] ==============================================")
|
|
507
|
+
raise Exception(
|
|
508
|
+
"❌ Permissions insuffisantes. Contactez votre IT Admin pour ajouter Mail.Read et Mail.Send permissions à l'application IA-ODATAMINING.")
|
|
509
|
+
else:
|
|
510
|
+
raise e
|
|
511
|
+
if not emails_data.get('value'):
|
|
512
|
+
print("Aucun nouveau mail.")
|
|
513
|
+
else:
|
|
514
|
+
for i, email_item in enumerate(emails_data['value']):
|
|
515
|
+
print(f"🔍 [DEBUG] Traitement de l'email {i + 1}/{len(emails_data['value'])}")
|
|
516
|
+
if list_agent_email:
|
|
517
|
+
white_list, black_list = offuscation_basique.lire_list_email(list_agent_email)
|
|
518
|
+
print(f"🔍 [DEBUG] Listes chargées - White: {len(white_list)}, Black: {len(black_list)}")
|
|
519
|
+
else:
|
|
520
|
+
white_list, black_list = [], []
|
|
521
|
+
|
|
522
|
+
time.sleep(1.5)
|
|
523
|
+
output_lines = []
|
|
524
|
+
|
|
525
|
+
email_id = email_item['id']
|
|
526
|
+
from_ = email_item['sender']['emailAddress']['address']
|
|
527
|
+
subject = email_item.get('subject', '(Sans sujet)')
|
|
528
|
+
to_emails = [rec['emailAddress']['address'] for rec in email_item.get('toRecipients', [])]
|
|
529
|
+
cc_emails = [rec['emailAddress']['address'] for rec in email_item.get('ccRecipients', [])]
|
|
530
|
+
|
|
531
|
+
print(f"🔍 [DEBUG] Email ID: {email_id}")
|
|
532
|
+
print(f"🔍 [DEBUG] De: {from_}, Sujet: {subject}")
|
|
533
|
+
print(f"🔍 [DEBUG] Destinataires: {to_emails}, CC: {cc_emails}")
|
|
534
|
+
|
|
535
|
+
# Marquer comme lu
|
|
536
|
+
mark_read_url = f"https://graph.microsoft.com/v1.0/users/{user_email}/messages/{email_id}"
|
|
537
|
+
patch_data = {'isRead': True}
|
|
538
|
+
print(f"🔍 [DEBUG] Marquage comme lu: {mark_read_url}")
|
|
539
|
+
requests.patch(mark_read_url, headers=headers, json=patch_data)
|
|
540
|
+
|
|
541
|
+
# Récupérer le corps du message
|
|
542
|
+
body = ""
|
|
543
|
+
if email_item.get('body'):
|
|
544
|
+
body_content = email_item['body'].get('content', '')
|
|
545
|
+
if email_item['body'].get('contentType') == 'html':
|
|
546
|
+
print("🔍 [DEBUG] Corps HTML détecté, nettoyage en cours")
|
|
547
|
+
soup = BeautifulSoup(body_content, "html.parser")
|
|
548
|
+
for block in soup.find_all(["footer", "style", "script"]):
|
|
549
|
+
block.decompose()
|
|
550
|
+
body = soup.get_text(separator="\n", strip=True)
|
|
551
|
+
else:
|
|
552
|
+
body = body_content.strip()
|
|
553
|
+
print(f"🔍 [DEBUG] Corps du message extrait (longueur: {len(body)})")
|
|
554
|
+
|
|
555
|
+
folder = mail_in_folder(user_email, "in")
|
|
556
|
+
if folder is None:
|
|
557
|
+
print("Erreur dans le folder de mail")
|
|
558
|
+
continue
|
|
559
|
+
print(f"🔍 [DEBUG] Dossier de mail: {folder}")
|
|
560
|
+
|
|
561
|
+
ignored_pj = ""
|
|
562
|
+
# Traiter les pièces jointes si elles existent
|
|
563
|
+
if email_item.get('hasAttachments'):
|
|
564
|
+
print("🔍 [DEBUG] Pièces jointes détectées, récupération en cours")
|
|
565
|
+
attachments_url = f"https://graph.microsoft.com/v1.0/users/{user_email}/messages/{email_id}/attachments"
|
|
566
|
+
att_response = requests.get(attachments_url, headers=headers)
|
|
567
|
+
att_response.raise_for_status()
|
|
568
|
+
attachments_data = att_response.json()
|
|
569
|
+
|
|
570
|
+
print(f"🔍 [DEBUG] {len(attachments_data.get('value', []))} pièce(s) jointe(s) trouvée(s)")
|
|
571
|
+
for attachment in attachments_data.get('value', []):
|
|
572
|
+
attachment_name = attachment.get('name', '')
|
|
573
|
+
print(f"🔍 [DEBUG] Pièce jointe: {attachment_name}")
|
|
574
|
+
if len(attachment_name) < 5:
|
|
575
|
+
continue
|
|
576
|
+
if not (attachment_name.endswith(".pdf") or attachment_name.endswith(".docx")):
|
|
577
|
+
ignored_pj += (";" if ignored_pj else "") + attachment_name
|
|
578
|
+
print(f"🔍 [DEBUG] Pièce jointe ignorée: {attachment_name}")
|
|
579
|
+
continue
|
|
580
|
+
|
|
581
|
+
folder_pj = os.path.join(folder, "pj")
|
|
582
|
+
os.makedirs(folder_pj, exist_ok=True)
|
|
583
|
+
filepath = os.path.join(folder_pj, attachment_name)
|
|
584
|
+
|
|
585
|
+
# Décoder le contenu base64
|
|
586
|
+
content_bytes = base64.b64decode(attachment.get('contentBytes', ''))
|
|
587
|
+
with open(filepath, "wb") as f:
|
|
588
|
+
f.write(content_bytes)
|
|
589
|
+
print(f"🔍 [DEBUG] Pièce jointe sauvegardée: {filepath}")
|
|
590
|
+
|
|
591
|
+
# Format sortie
|
|
592
|
+
output_lines = [
|
|
593
|
+
f"#$who : {user_email}",
|
|
594
|
+
f"#$eme : {from_}",
|
|
595
|
+
f"#$des : {', '.join(to_emails)}",
|
|
596
|
+
f"#$cop : {', '.join(cc_emails)}",
|
|
597
|
+
"#$pri : Normale",
|
|
598
|
+
f"#$tit : {subject}",
|
|
599
|
+
f"#$ipj : {ignored_pj}",
|
|
600
|
+
f"#$txt : {body.strip()}",
|
|
601
|
+
""
|
|
602
|
+
]
|
|
603
|
+
|
|
604
|
+
print("----------------------------------------")
|
|
605
|
+
print(f"Mail reçu de {from_}")
|
|
606
|
+
print("----------------------------------------")
|
|
607
|
+
|
|
608
|
+
if white_list and from_ not in white_list:
|
|
609
|
+
print("Cette adresse n'est pas dans la white list")
|
|
610
|
+
continue
|
|
611
|
+
if black_list and from_ in black_list:
|
|
612
|
+
print("Cette adresse est dans la black list")
|
|
613
|
+
continue
|
|
614
|
+
|
|
615
|
+
mail_txt_path = os.path.join(folder, "mail.txt")
|
|
616
|
+
mail_ok_path = os.path.join(folder, "mail.ok")
|
|
617
|
+
print(f"🔍 [DEBUG] Sauvegarde du mail: {mail_txt_path}")
|
|
618
|
+
with open(mail_txt_path, "w", encoding="utf-8") as f:
|
|
619
|
+
f.write("\n".join(output_lines))
|
|
620
|
+
with open(mail_ok_path, "w") as f:
|
|
621
|
+
pass
|
|
622
|
+
print("🔍 [DEBUG] Fichiers créés: mail.txt et mail.ok")
|
|
434
623
|
|
|
624
|
+
print("🔍 [DEBUG] Vérification des emails terminée")
|
|
435
625
|
|
|
436
626
|
except Exception as e:
|
|
437
|
-
print(f"Erreur
|
|
627
|
+
print(f"Erreur Graph API lors du traitement du mail : {e}")
|
|
628
|
+
print(f"🔍 [DEBUG] Erreur détaillée: {type(e).__name__}: {str(e)}")
|
|
629
|
+
|
|
438
630
|
|
|
439
631
|
else:
|
|
440
632
|
print("type de co non géré : attendu IMAP4_SSL, MICROSOFT_EXCHANGE_OWA ou MICROSOFT_EXCHANGE_OAUTH2")
|
|
@@ -665,6 +857,137 @@ def check_send_new_emails(offusc_conf_agent,type_co):
|
|
|
665
857
|
print("Le dossier n'existe pas ou le chemin n'est pas un dossier.")
|
|
666
858
|
except Exception as e:
|
|
667
859
|
print(f"❌ Erreur lors de l'envoi avec OAuth2 : {e}")
|
|
860
|
+
elif type_co == "MICROSOFT_EXCHANGE_OAUTH2_MICROSOFT_GRAPH":
|
|
861
|
+
try:
|
|
862
|
+
print("📤 [DEBUG] Début de la vérification des emails à envoyer avec Microsoft Graph OAuth2")
|
|
863
|
+
client_id, client_secret, tenant_id, user_email = offuscation_basique.lire_config_cli_oauth2(
|
|
864
|
+
offusc_conf_agent)
|
|
865
|
+
print(f"📤 [DEBUG] Configuration lue - User: {user_email}, Tenant: {tenant_id}")
|
|
866
|
+
|
|
867
|
+
# Déduire l'alias pour le nom du dossier
|
|
868
|
+
agent = user_email
|
|
869
|
+
alias = user_email # tu peux adapter si tu veux un alias distinct plus tard
|
|
870
|
+
|
|
871
|
+
chemin_dossier_in, chemin_dossier_out = mail_in_folder(agent, "out")
|
|
872
|
+
print(f"📤 [DEBUG] Dossiers - In: {chemin_dossier_in}, Out: {chemin_dossier_out}")
|
|
873
|
+
|
|
874
|
+
authority = f"https://login.microsoftonline.com/{tenant_id}"
|
|
875
|
+
|
|
876
|
+
# === Authentification avec MSAL ===
|
|
877
|
+
app = ConfidentialClientApplication(
|
|
878
|
+
client_id=client_id,
|
|
879
|
+
client_credential=client_secret,
|
|
880
|
+
authority=authority
|
|
881
|
+
)
|
|
882
|
+
print("📤 [DEBUG] Application MSAL créée")
|
|
883
|
+
|
|
884
|
+
token_result = app.acquire_token_for_client(scopes=["https://graph.microsoft.com/.default"])
|
|
885
|
+
|
|
886
|
+
if "access_token" not in token_result:
|
|
887
|
+
raise Exception("Impossible d'obtenir un token : ", token_result.get("error_description"))
|
|
888
|
+
|
|
889
|
+
print("📤 [DEBUG] Token d'accès obtenu avec succès (Client Credentials)")
|
|
890
|
+
access_token = token_result['access_token']
|
|
891
|
+
headers = {
|
|
892
|
+
'Authorization': f'Bearer {access_token}',
|
|
893
|
+
'Content-Type': 'application/json'
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
if os.path.exists(chemin_dossier_out) and os.path.isdir(chemin_dossier_out):
|
|
897
|
+
print("📤 [DEBUG] Dossier de sortie trouvé, lecture du contenu")
|
|
898
|
+
contenus = os.listdir(chemin_dossier_out)
|
|
899
|
+
print(f"📤 [DEBUG] Contenu du dossier: {contenus}")
|
|
900
|
+
if contenus:
|
|
901
|
+
for contenu in contenus:
|
|
902
|
+
mail_ok_path = os.path.join(chemin_dossier_out, contenu, "mail.ok")
|
|
903
|
+
print(f"📤 [DEBUG] Vérification du fichier mail.ok: {mail_ok_path}")
|
|
904
|
+
if os.path.exists(mail_ok_path):
|
|
905
|
+
chemin = os.path.join(chemin_dossier_out, contenu, "mail.txt")
|
|
906
|
+
print(f"📤 [DEBUG] Lecture du message depuis: {chemin}")
|
|
907
|
+
infos = lire_message(chemin)
|
|
908
|
+
print(f"📤 [DEBUG] Informations du message lues: {list(infos.keys())}")
|
|
909
|
+
|
|
910
|
+
cles_requises = ["eme", "des", "cop", "pri", "tit", "txt"]
|
|
911
|
+
if all(cle in infos for cle in cles_requises):
|
|
912
|
+
print("📤 [DEBUG] Toutes les clés requises sont présentes")
|
|
913
|
+
print(f"📤 [DEBUG] Envoi vers: {infos['eme']}")
|
|
914
|
+
print(f"📤 [DEBUG] Sujet: {infos['tit']}")
|
|
915
|
+
print(f"📤 [DEBUG] Contenu (longueur): {len(infos['txt'])}")
|
|
916
|
+
|
|
917
|
+
# Construire le message pour Microsoft Graph
|
|
918
|
+
message_data = {
|
|
919
|
+
"message": {
|
|
920
|
+
"subject": infos["tit"],
|
|
921
|
+
"body": {
|
|
922
|
+
"contentType": "HTML",
|
|
923
|
+
"content": infos["txt"]
|
|
924
|
+
},
|
|
925
|
+
"toRecipients": [
|
|
926
|
+
{
|
|
927
|
+
"emailAddress": {
|
|
928
|
+
"address": infos["eme"]
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
]
|
|
932
|
+
},
|
|
933
|
+
"saveToSentItems": True
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
# Envoyer l'email via Microsoft Graph
|
|
937
|
+
send_url = f"https://graph.microsoft.com/v1.0/users/{user_email}/sendMail"
|
|
938
|
+
print(f"📤 [DEBUG] Envoi via Graph API: {send_url}")
|
|
939
|
+
try:
|
|
940
|
+
response = requests.post(send_url, headers=headers, json=message_data)
|
|
941
|
+
response.raise_for_status()
|
|
942
|
+
print("📤 [DEBUG] Email envoyé avec succès")
|
|
943
|
+
except requests.exceptions.HTTPError as e:
|
|
944
|
+
if response.status_code == 403:
|
|
945
|
+
print("📤 [DEBUG] Erreur 403 - Permissions insuffisantes pour l'envoi")
|
|
946
|
+
print("📤 [DEBUG] ==============================================")
|
|
947
|
+
print("📤 [DEBUG] ACTION REQUISE - Contactez votre IT Admin:")
|
|
948
|
+
print("📤 [DEBUG] ==============================================")
|
|
949
|
+
print("📤 [DEBUG] Permission manquante: Mail.Send (Application)")
|
|
950
|
+
print("📤 [DEBUG] App: IA-ODATAMINING")
|
|
951
|
+
print("📤 [DEBUG] ID: 30ae55f5-f41e-4d44-afcc-082e4b803ba1")
|
|
952
|
+
print("📤 [DEBUG] Tenant: 9988c2b8-3feb-4426-aeb7-b8d695bcd025")
|
|
953
|
+
print("📤 [DEBUG] ")
|
|
954
|
+
print("📤 [DEBUG] INFORMATIONS POUR VOTRE IT ADMIN:")
|
|
955
|
+
print("📤 [DEBUG] 1. Azure Portal → Azure AD → App registrations")
|
|
956
|
+
print("📤 [DEBUG] 2. Trouver l'app: IA-ODATAMINING")
|
|
957
|
+
print("📤 [DEBUG] 3. API permissions → Add permission → Microsoft Graph")
|
|
958
|
+
print("📤 [DEBUG] 4. Application permissions → Mail.Send")
|
|
959
|
+
print("📤 [DEBUG] 5. Grant admin consent")
|
|
960
|
+
print("📤 [DEBUG] ==============================================")
|
|
961
|
+
raise Exception(
|
|
962
|
+
"❌ Permission Mail.Send manquante. Contactez votre IT Admin pour ajouter cette permission à l'application IA-ODATAMINING.")
|
|
963
|
+
else:
|
|
964
|
+
raise e
|
|
965
|
+
|
|
966
|
+
time.sleep(1)
|
|
967
|
+
print("📤 [DEBUG] Nettoyage des dossiers")
|
|
968
|
+
MetManagement.reset_folder(os.path.join(chemin_dossier_in, contenu), recreate=False)
|
|
969
|
+
MetManagement.reset_folder(os.path.join(chemin_dossier_out, contenu), recreate=False)
|
|
970
|
+
print("📤 [DEBUG] Dossiers nettoyés")
|
|
971
|
+
else:
|
|
972
|
+
print("\n\n Il manque des clefs dans le contenu du mail")
|
|
973
|
+
print(
|
|
974
|
+
f"📤 [DEBUG] Clés manquantes: {[cle for cle in cles_requises if cle not in infos]}")
|
|
975
|
+
else:
|
|
976
|
+
print(
|
|
977
|
+
f"\n\n KO § os.path.exists(os.path.join(chemin_dossier_out, contenu): {os.path.exists(os.path.join(chemin_dossier_out, contenu, 'mail.ok'))}")
|
|
978
|
+
else:
|
|
979
|
+
print("Le dossier est vide.")
|
|
980
|
+
else:
|
|
981
|
+
print("Le dossier n'existe pas ou le chemin n'est pas un dossier.")
|
|
982
|
+
print(f"📤 [DEBUG] Chemin vérifié: {chemin_dossier_out}")
|
|
983
|
+
print(
|
|
984
|
+
f"📤 [DEBUG] Existe: {os.path.exists(chemin_dossier_out)}, Est dossier: {os.path.isdir(chemin_dossier_out) if os.path.exists(chemin_dossier_out) else 'N/A'}")
|
|
985
|
+
|
|
986
|
+
print("📤 [DEBUG] Vérification des emails à envoyer terminée")
|
|
987
|
+
|
|
988
|
+
except Exception as e:
|
|
989
|
+
print(f"❌ Erreur lors de l'envoi avec Graph API : {e}")
|
|
990
|
+
print(f"📤 [DEBUG] Erreur détaillée: {type(e).__name__}: {str(e)}")
|
|
668
991
|
else:
|
|
669
992
|
print("type de co non valide")
|
|
670
993
|
|