Maintainers
+Maintainers
This module is maintained by the OCA.
@@ -456,6 +451,5 @@ diff --git a/fs_folder/fields.py b/fs_folder/fields.py index f1d92c8916..d539f4eac2 100644 --- a/fs_folder/fields.py +++ b/fs_folder/fields.py @@ -1,5 +1,6 @@ # Copyright 2024 ACSONE SA/NV # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). +import logging import threading import time import typing @@ -7,7 +8,7 @@ import fsspec -from odoo import SUPERUSER_ID, api, fields, models, registry +from odoo import api, fields, models, registry from odoo.tools.misc import SENTINEL, Sentinel from odoo.tools.sql import pg_varchar @@ -15,6 +16,8 @@ from .models.fs_storage import FsStorage +_logger = logging.getLogger(__name__) + class FsContentValue: def __init__( @@ -352,14 +355,17 @@ def create_value_in_fs(self, records: models.BaseModel) -> list[FsFolderValue]: fs.mkdir(path, **kwargs) - def clean_up_folder(path, storage_code, dbname): + def clean_up_folder(path, storage_code, dbname, user_id): db_registry = registry(dbname) with db_registry.cursor() as cr: - env = api.Environment(cr, SUPERUSER_ID, {}) + env = api.Environment(cr, user_id, {}) fs = env["fs.storage"].get_fs_by_code(storage_code) time.sleep(0.5) # wait creation into the filesystem - fs.rm(path, recursive=True) - # remove created resource in case of rollback + try: + # remove created resource in case of rollback + fs.rm(path, recursive=True) + except Exception as e: + _logger.exception(f"Error cleaning up folder {path}: {e}") test_mode = getattr(threading.current_thread(), "testing", False) if not test_mode: @@ -369,6 +375,7 @@ def clean_up_folder(path, storage_code, dbname): path, storage_code, record.env.cr.dbname, + record.env.user.id, ), ) diff --git a/fs_folder_ms_drive/models/fs_folder_field_value_adapter.py b/fs_folder_ms_drive/models/fs_folder_field_value_adapter.py index a9783d3efd..2afc535266 100644 --- a/fs_folder_ms_drive/models/fs_folder_field_value_adapter.py +++ b/fs_folder_ms_drive/models/fs_folder_field_value_adapter.py @@ -42,9 +42,10 @@ def _parse_fs_folder_value( ref, storage_code = super()._parse_fs_folder_value(stored_value, field, record) if ref: fs = record.env["fs.storage"].sudo().get_fs_by_code(storage_code) - if ( - self._is_msgraph_folder(fs) - and self.env.user.microsoft_drive_status == "connected" + user = record.env.user + if self._is_msgraph_folder(fs) and ( + user.microsoft_drive_oauth2_non_interactive + or user.microsoft_drive_status == "connected" ): fs_info = fs.info(path=ref, item_id=ref, details=False) ref = fs_info.get("name") diff --git a/fs_storage_ms_drive/models/fs_storage.py b/fs_storage_ms_drive/models/fs_storage.py index 5948d18218..24c0619601 100644 --- a/fs_storage_ms_drive/models/fs_storage.py +++ b/fs_storage_ms_drive/models/fs_storage.py @@ -23,15 +23,17 @@ def _get_filesystem(self): while hasattr(root_fs, "fs"): root_fs = fs.fs client = root_fs.client - client.register_compliance_hook( - "refresh_token_response", - partial( - self.update_refresh_token_on_user, - client=client, - db_name=self._cr.dbname, - user_id=self.env.user.id, - ), - ) + if not self.env.user.microsoft_drive_oauth2_non_interactive: + # In interactive mode, we need to update the refresh token on user + client.register_compliance_hook( + "refresh_token_response", + partial( + self.update_refresh_token_on_user, + client=client, + db_name=self._cr.dbname, + user_id=self.env.user.id, + ), + ) return fs @api.model diff --git a/fs_storage_ms_drive/models/res_user.py b/fs_storage_ms_drive/models/res_user.py index df47a4b2be..e599f65232 100644 --- a/fs_storage_ms_drive/models/res_user.py +++ b/fs_storage_ms_drive/models/res_user.py @@ -14,26 +14,31 @@ def _get_oauth2_client_params(self): return { "client_id": get_param("microsoft_drive_client_id"), "client_secret": get_param("microsoft_drive_client_secret"), - "scope": self.env["microsoft.service"]._get_drive_scope(), "token_endpoint": get_param("microsoft_account.token_endpoint"), } def _get_oauth2_params(self): self.ensure_one() - access_token = self.microsoft_drive_token - rtoken = self.microsoft_drive_rtoken - expires_at = -1 - if self.microsoft_drive_token_validity: - # Convert datetime to timestamp - # This is needed for compatibility with authlib - # which expects an integer timestamp. - # If the token validity is not set, we use -1 to indicate no expiry. - expires_at = int(self.microsoft_drive_token_validity.timestamp()) - token = { - "access_token": access_token, - "refresh_token": rtoken, - "expires_at": expires_at, - } params = self._get_oauth2_client_params() - params.update(token=token) + if self.microsoft_drive_oauth2_non_interactive: + params["grant_type"] = "client_credentials" + params["scope"] = "https://graph.microsoft.com/.default" + else: + params["grant_type"] = "refresh_token" + params["scope"] = self.env["microsoft.service"]._get_drive_scope() + access_token = self.microsoft_drive_token + rtoken = self.microsoft_drive_rtoken + expires_at = -1 + if self.microsoft_drive_token_validity: + # Convert datetime to timestamp + # This is needed for compatibility with authlib + # which expects an integer timestamp. + # If the token validity is not set, we use -1 to indicate no expiry. + expires_at = int(self.microsoft_drive_token_validity.timestamp()) + token = { + "access_token": access_token, + "refresh_token": rtoken, + "expires_at": expires_at, + } + params["token"] = token return params diff --git a/fs_storage_ms_drive/static/description/index.html b/fs_storage_ms_drive/static/description/index.html index 42c2977a08..bade2cc725 100644 --- a/fs_storage_ms_drive/static/description/index.html +++ b/fs_storage_ms_drive/static/description/index.html @@ -3,7 +3,7 @@
-This addon extends the functionality of the fs_storage module to allow the system to use Microsoft Drives (OneDrive, @@ -411,7 +406,7 @@
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed @@ -419,29 +414,29 @@
Do not contact contributors directly about support or help with technical issues.
The development of this module has been financially supported by: