Skip to content

Commit aee654b

Browse files
committed
Merge PR #528 into 18.0
Signed-off-by lmignon
2 parents 4db3181 + 98a2721 commit aee654b

File tree

7 files changed

+74
-50
lines changed

7 files changed

+74
-50
lines changed

fs_folder/fields.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
# Copyright 2024 ACSONE SA/NV
22
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).
3+
import logging
34
import threading
45
import time
56
import typing
67
from functools import partial
78

89
import fsspec
910

10-
from odoo import SUPERUSER_ID, api, fields, models, registry
11+
from odoo import api, fields, models, registry
1112
from odoo.tools.misc import SENTINEL, Sentinel
1213
from odoo.tools.sql import pg_varchar
1314

1415
from odoo.addons.fs_storage.rooted_dir_file_system import RootedDirFileSystem
1516

1617
from .models.fs_storage import FsStorage
1718

19+
_logger = logging.getLogger(__name__)
20+
1821

1922
class FsContentValue:
2023
def __init__(
@@ -352,14 +355,17 @@ def create_value_in_fs(self, records: models.BaseModel) -> list[FsFolderValue]:
352355

353356
fs.mkdir(path, **kwargs)
354357

355-
def clean_up_folder(path, storage_code, dbname):
358+
def clean_up_folder(path, storage_code, dbname, user_id):
356359
db_registry = registry(dbname)
357360
with db_registry.cursor() as cr:
358-
env = api.Environment(cr, SUPERUSER_ID, {})
361+
env = api.Environment(cr, user_id, {})
359362
fs = env["fs.storage"].get_fs_by_code(storage_code)
360363
time.sleep(0.5) # wait creation into the filesystem
361-
fs.rm(path, recursive=True)
362-
# remove created resource in case of rollback
364+
try:
365+
# remove created resource in case of rollback
366+
fs.rm(path, recursive=True)
367+
except Exception as e:
368+
_logger.exception(f"Error cleaning up folder {path}: {e}")
363369

364370
test_mode = getattr(threading.current_thread(), "testing", False)
365371
if not test_mode:
@@ -369,6 +375,7 @@ def clean_up_folder(path, storage_code, dbname):
369375
path,
370376
storage_code,
371377
record.env.cr.dbname,
378+
record.env.user.id,
372379
),
373380
)
374381

fs_folder_ms_drive/models/fs_folder_field_value_adapter.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,10 @@ def _parse_fs_folder_value(
4242
ref, storage_code = super()._parse_fs_folder_value(stored_value, field, record)
4343
if ref:
4444
fs = record.env["fs.storage"].sudo().get_fs_by_code(storage_code)
45-
if (
46-
self._is_msgraph_folder(fs)
47-
and self.env.user.microsoft_drive_status == "connected"
45+
user = record.env.user
46+
if self._is_msgraph_folder(fs) and (
47+
user.microsoft_drive_oauth2_non_interactive
48+
or user.microsoft_drive_status == "connected"
4849
):
4950
fs_info = fs.info(path=ref, item_id=ref, details=False)
5051
ref = fs_info.get("name")

fs_storage_ms_drive/models/fs_storage.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,17 @@ def _get_filesystem(self):
2323
while hasattr(root_fs, "fs"):
2424
root_fs = fs.fs
2525
client = root_fs.client
26-
client.register_compliance_hook(
27-
"refresh_token_response",
28-
partial(
29-
self.update_refresh_token_on_user,
30-
client=client,
31-
db_name=self._cr.dbname,
32-
user_id=self.env.user.id,
33-
),
34-
)
26+
if not self.env.user.microsoft_drive_oauth2_non_interactive:
27+
# In interactive mode, we need to update the refresh token on user
28+
client.register_compliance_hook(
29+
"refresh_token_response",
30+
partial(
31+
self.update_refresh_token_on_user,
32+
client=client,
33+
db_name=self._cr.dbname,
34+
user_id=self.env.user.id,
35+
),
36+
)
3537
return fs
3638

3739
@api.model

fs_storage_ms_drive/models/res_user.py

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,31 @@ def _get_oauth2_client_params(self):
1414
return {
1515
"client_id": get_param("microsoft_drive_client_id"),
1616
"client_secret": get_param("microsoft_drive_client_secret"),
17-
"scope": self.env["microsoft.service"]._get_drive_scope(),
1817
"token_endpoint": get_param("microsoft_account.token_endpoint"),
1918
}
2019

2120
def _get_oauth2_params(self):
2221
self.ensure_one()
23-
access_token = self.microsoft_drive_token
24-
rtoken = self.microsoft_drive_rtoken
25-
expires_at = -1
26-
if self.microsoft_drive_token_validity:
27-
# Convert datetime to timestamp
28-
# This is needed for compatibility with authlib
29-
# which expects an integer timestamp.
30-
# If the token validity is not set, we use -1 to indicate no expiry.
31-
expires_at = int(self.microsoft_drive_token_validity.timestamp())
32-
token = {
33-
"access_token": access_token,
34-
"refresh_token": rtoken,
35-
"expires_at": expires_at,
36-
}
3722
params = self._get_oauth2_client_params()
38-
params.update(token=token)
23+
if self.microsoft_drive_oauth2_non_interactive:
24+
params["grant_type"] = "client_credentials"
25+
params["scope"] = "https://graph.microsoft.com/.default"
26+
else:
27+
params["grant_type"] = "refresh_token"
28+
params["scope"] = self.env["microsoft.service"]._get_drive_scope()
29+
access_token = self.microsoft_drive_token
30+
rtoken = self.microsoft_drive_rtoken
31+
expires_at = -1
32+
if self.microsoft_drive_token_validity:
33+
# Convert datetime to timestamp
34+
# This is needed for compatibility with authlib
35+
# which expects an integer timestamp.
36+
# If the token validity is not set, we use -1 to indicate no expiry.
37+
expires_at = int(self.microsoft_drive_token_validity.timestamp())
38+
token = {
39+
"access_token": access_token,
40+
"refresh_token": rtoken,
41+
"expires_at": expires_at,
42+
}
43+
params["token"] = token
3944
return params

fs_storage_ms_drive/static/description/index.html

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<head>
44
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
55
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
6-
<title>README.rst</title>
6+
<title>Filesystem Storage For Microsoft Drives</title>
77
<style type="text/css">
88

99
/*
@@ -360,21 +360,16 @@
360360
</style>
361361
</head>
362362
<body>
363-
<div class="document">
363+
<div class="document" id="filesystem-storage-for-microsoft-drives">
364+
<h1 class="title">Filesystem Storage For Microsoft Drives</h1>
364365

365-
366-
<a class="reference external image-reference" href="https://odoo-community.org/get-involved?utm_source=readme">
367-
<img alt="Odoo Community Association" src="https://odoo-community.org/readme-banner-image" />
368-
</a>
369-
<div class="section" id="filesystem-storage-for-microsoft-drives">
370-
<h1>Filesystem Storage For Microsoft Drives</h1>
371366
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
372367
!! This file is generated by oca-gen-addon-readme !!
373368
!! changes will be overwritten. !!
374369
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
375370
!! source digest: sha256:b5c56d23130eafeaaad1b4ab5a776a5464631a2ade4f354b1fed51a23f7f2ada
376371
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
377-
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/lgpl-3.0-standalone.html"><img alt="License: LGPL-3" src="https://img.shields.io/badge/license-LGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/storage/tree/18.0/fs_storage_ms_drive"><img alt="OCA/storage" src="https://img.shields.io/badge/github-OCA%2Fstorage-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/storage-18-0/storage-18-0-fs_storage_ms_drive"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/storage&amp;target_branch=18.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
372+
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/lgpl-3.0-standalone.html"><img alt="License: LGPL-3" src="https://img.shields.io/badge/licence-LGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/storage/tree/18.0/fs_storage_ms_drive"><img alt="OCA/storage" src="https://img.shields.io/badge/github-OCA%2Fstorage-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/storage-18-0/storage-18-0-fs_storage_ms_drive"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/storage&amp;target_branch=18.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
378373
<p>This addon extends the functionality of the
379374
<a class="reference external" href="https://github.com/OCA/storage/tree/18.0/fs_storage">fs_storage</a>
380375
module to allow the system to use Microsoft Drives (OneDrive,
@@ -411,37 +406,37 @@ <h1>Filesystem Storage For Microsoft Drives</h1>
411406
</ul>
412407
</div>
413408
<div class="section" id="bug-tracker">
414-
<h2><a class="toc-backref" href="#toc-entry-1">Bug Tracker</a></h2>
409+
<h1><a class="toc-backref" href="#toc-entry-1">Bug Tracker</a></h1>
415410
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/storage/issues">GitHub Issues</a>.
416411
In case of trouble, please check there if your issue has already been reported.
417412
If you spotted it first, help us to smash it by providing a detailed and welcomed
418413
<a class="reference external" href="https://github.com/OCA/storage/issues/new?body=module:%20fs_storage_ms_drive%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
419414
<p>Do not contact contributors directly about support or help with technical issues.</p>
420415
</div>
421416
<div class="section" id="credits">
422-
<h2><a class="toc-backref" href="#toc-entry-2">Credits</a></h2>
417+
<h1><a class="toc-backref" href="#toc-entry-2">Credits</a></h1>
423418
<div class="section" id="authors">
424-
<h3><a class="toc-backref" href="#toc-entry-3">Authors</a></h3>
419+
<h2><a class="toc-backref" href="#toc-entry-3">Authors</a></h2>
425420
<ul class="simple">
426421
<li>ACSONE SA/NV</li>
427422
</ul>
428423
</div>
429424
<div class="section" id="contributors">
430-
<h3><a class="toc-backref" href="#toc-entry-4">Contributors</a></h3>
425+
<h2><a class="toc-backref" href="#toc-entry-4">Contributors</a></h2>
431426
<ul class="simple">
432427
<li>Laurent Mignon &lt;<a class="reference external" href="mailto:laurent.mignon&#64;acsone.eu">laurent.mignon&#64;acsone.eu</a>&gt;</li>
433428
<li>Pierre Halleux &lt;<a class="reference external" href="mailto:pierre.halleux&#64;acsone.eu">pierre.halleux&#64;acsone.eu</a>&gt;</li>
434429
</ul>
435430
</div>
436431
<div class="section" id="other-credits">
437-
<h3><a class="toc-backref" href="#toc-entry-5">Other credits</a></h3>
432+
<h2><a class="toc-backref" href="#toc-entry-5">Other credits</a></h2>
438433
<p>The development of this module has been financially supported by:</p>
439434
<ul class="simple">
440435
<li>ACSONE SA/NV</li>
441436
</ul>
442437
</div>
443438
<div class="section" id="maintainers">
444-
<h3><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h3>
439+
<h2><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h2>
445440
<p>This module is maintained by the OCA.</p>
446441
<a class="reference external image-reference" href="https://odoo-community.org">
447442
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
@@ -456,6 +451,5 @@ <h3><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h3>
456451
</div>
457452
</div>
458453
</div>
459-
</div>
460454
</body>
461455
</html>

microsoft_drive_account/models/res_users.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,16 @@ class ResUsers(models.Model):
2626
store=True,
2727
)
2828

29+
microsoft_drive_oauth2_non_interactive = fields.Boolean(
30+
string="Microsoft Drive OAuth2 (non-interactive)",
31+
default=False,
32+
help="If set, this user will not go through the interactive OAuth2 "
33+
"authorization flow; The requested token will be requested to the "
34+
"authentication server directly using client credentials flows. "
35+
"(scope: 'https://graph.microsoft.com/.default', "
36+
"grante_type: 'client_credentials')",
37+
)
38+
2939
def _set_microsoft_drive_auth_tokens(
3040
self, access_token: str, refresh_token: str, ttl: float
3141
):

microsoft_drive_account/views/res_users.xml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,13 @@
99
<field name="arch" type="xml">
1010
<page name="account_security" position="inside">
1111
<group string="Drive" name="drive_group">
12+
<group>
13+
<field name="microsoft_drive_oauth2_non_interactive" />
14+
</group>
1215
<field name="microsoft_drive_status" widget="ms_drive_connect" />
13-
<group invisible="microsoft_drive_status == 'not_connected'">
16+
<group
17+
invisible="not microsoft_drive_oauth2_non_interactive or microsoft_drive_status == 'not_connected'"
18+
>
1419
<field
1520
name="microsoft_drive_token_validity"
1621
string="Token Validity"

0 commit comments

Comments
 (0)