Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions fs_folder/fields.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
# 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
from functools import partial

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

from odoo.addons.fs_storage.rooted_dir_file_system import RootedDirFileSystem

from .models.fs_storage import FsStorage

_logger = logging.getLogger(__name__)


class FsContentValue:
def __init__(
Expand Down Expand Up @@ -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:
Expand All @@ -369,6 +375,7 @@ def clean_up_folder(path, storage_code, dbname):
path,
storage_code,
record.env.cr.dbname,
record.env.user.id,
),
)

Expand Down
7 changes: 4 additions & 3 deletions fs_folder_ms_drive/models/fs_folder_field_value_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
20 changes: 11 additions & 9 deletions fs_storage_ms_drive/models/fs_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
37 changes: 21 additions & 16 deletions fs_storage_ms_drive/models/res_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
26 changes: 10 additions & 16 deletions fs_storage_ms_drive/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>README.rst</title>
<title>Filesystem Storage For Microsoft Drives</title>
<style type="text/css">

/*
Expand Down Expand Up @@ -360,21 +360,16 @@
</style>
</head>
<body>
<div class="document">
<div class="document" id="filesystem-storage-for-microsoft-drives">
<h1 class="title">Filesystem Storage For Microsoft Drives</h1>


<a class="reference external image-reference" href="https://odoo-community.org/get-involved?utm_source=readme">
<img alt="Odoo Community Association" src="https://odoo-community.org/readme-banner-image" />
</a>
<div class="section" id="filesystem-storage-for-microsoft-drives">
<h1>Filesystem Storage For Microsoft Drives</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:b5c56d23130eafeaaad1b4ab5a776a5464631a2ade4f354b1fed51a23f7f2ada
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<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>
<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>
<p>This addon extends the functionality of the
<a class="reference external" href="https://github.com/OCA/storage/tree/18.0/fs_storage">fs_storage</a>
module to allow the system to use Microsoft Drives (OneDrive,
Expand Down Expand Up @@ -411,37 +406,37 @@ <h1>Filesystem Storage For Microsoft Drives</h1>
</ul>
</div>
<div class="section" id="bug-tracker">
<h2><a class="toc-backref" href="#toc-entry-1">Bug Tracker</a></h2>
<h1><a class="toc-backref" href="#toc-entry-1">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/storage/issues">GitHub Issues</a>.
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
<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>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h2><a class="toc-backref" href="#toc-entry-2">Credits</a></h2>
<h1><a class="toc-backref" href="#toc-entry-2">Credits</a></h1>
<div class="section" id="authors">
<h3><a class="toc-backref" href="#toc-entry-3">Authors</a></h3>
<h2><a class="toc-backref" href="#toc-entry-3">Authors</a></h2>
<ul class="simple">
<li>ACSONE SA/NV</li>
</ul>
</div>
<div class="section" id="contributors">
<h3><a class="toc-backref" href="#toc-entry-4">Contributors</a></h3>
<h2><a class="toc-backref" href="#toc-entry-4">Contributors</a></h2>
<ul class="simple">
<li>Laurent Mignon &lt;<a class="reference external" href="mailto:laurent.mignon&#64;acsone.eu">laurent.mignon&#64;acsone.eu</a>&gt;</li>
<li>Pierre Halleux &lt;<a class="reference external" href="mailto:pierre.halleux&#64;acsone.eu">pierre.halleux&#64;acsone.eu</a>&gt;</li>
</ul>
</div>
<div class="section" id="other-credits">
<h3><a class="toc-backref" href="#toc-entry-5">Other credits</a></h3>
<h2><a class="toc-backref" href="#toc-entry-5">Other credits</a></h2>
<p>The development of this module has been financially supported by:</p>
<ul class="simple">
<li>ACSONE SA/NV</li>
</ul>
</div>
<div class="section" id="maintainers">
<h3><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h3>
<h2><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
Expand All @@ -456,6 +451,5 @@ <h3><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h3>
</div>
</div>
</div>
</div>
</body>
</html>
10 changes: 10 additions & 0 deletions microsoft_drive_account/models/res_users.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ class ResUsers(models.Model):
store=True,
)

microsoft_drive_oauth2_non_interactive = fields.Boolean(
string="Microsoft Drive OAuth2 (non-interactive)",
default=False,
help="If set, this user will not go through the interactive OAuth2 "
"authorization flow; The requested token will be requested to the "
"authentication server directly using client credentials flows. "
"(scope: 'https://graph.microsoft.com/.default', "
"grante_type: 'client_credentials')",
)

def _set_microsoft_drive_auth_tokens(
self, access_token: str, refresh_token: str, ttl: float
):
Expand Down
7 changes: 6 additions & 1 deletion microsoft_drive_account/views/res_users.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@
<field name="arch" type="xml">
<page name="account_security" position="inside">
<group string="Drive" name="drive_group">
<group>
<field name="microsoft_drive_oauth2_non_interactive" />
</group>
<field name="microsoft_drive_status" widget="ms_drive_connect" />
<group invisible="microsoft_drive_status == 'not_connected'">
<group
invisible="not microsoft_drive_oauth2_non_interactive or microsoft_drive_status == 'not_connected'"
>
<field
name="microsoft_drive_token_validity"
string="Token Validity"
Expand Down