odoo-addon-dms 17.0.1.2.0__py3-none-any.whl → 18.0.1.0.0.2__py3-none-any.whl
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.
- odoo/addons/dms/README.rst +69 -62
- odoo/addons/dms/__manifest__.py +1 -5
- odoo/addons/dms/data/onboarding_data.xml +0 -1
- odoo/addons/dms/i18n/de.po +0 -203
- odoo/addons/dms/i18n/dms.pot +51 -55
- odoo/addons/dms/i18n/es.po +0 -214
- odoo/addons/dms/i18n/fr.po +0 -45
- odoo/addons/dms/i18n/he_IL.po +0 -139
- odoo/addons/dms/i18n/it.po +0 -219
- odoo/addons/dms/i18n/nl.po +0 -6
- odoo/addons/dms/i18n/pt.po +0 -215
- odoo/addons/dms/i18n/pt_BR.po +0 -201
- odoo/addons/dms/models/access_groups.py +9 -8
- odoo/addons/dms/models/directory.py +21 -23
- odoo/addons/dms/models/dms_category.py +2 -2
- odoo/addons/dms/models/dms_file.py +15 -16
- odoo/addons/dms/models/dms_security_mixin.py +46 -20
- odoo/addons/dms/models/ir_binary.py +2 -2
- odoo/addons/dms/models/mixins_thumbnail.py +1 -1
- odoo/addons/dms/models/storage.py +3 -3
- odoo/addons/dms/readme/CONTRIBUTORS.md +2 -0
- odoo/addons/dms/readme/ROADMAP.md +2 -0
- odoo/addons/dms/static/description/index.html +13 -6
- odoo/addons/dms/static/src/js/fields/path_json/path_owl.esm.js +5 -5
- odoo/addons/dms/static/src/js/fields/preview_binary/preview_record.esm.js +2 -4
- odoo/addons/dms/static/src/js/views/dms_file_upload.esm.js +2 -5
- odoo/addons/dms/static/src/js/views/file_kanban_controller.esm.js +0 -2
- odoo/addons/dms/static/src/js/views/file_kanban_record.esm.js +0 -2
- odoo/addons/dms/static/src/js/views/file_kanban_renderer.esm.js +0 -2
- odoo/addons/dms/static/src/js/views/file_kanban_view.esm.js +0 -2
- odoo/addons/dms/static/src/js/views/file_list_controller.esm.js +0 -2
- odoo/addons/dms/static/src/js/views/file_list_renderer.esm.js +0 -2
- odoo/addons/dms/static/src/js/views/file_list_view.esm.js +0 -2
- odoo/addons/dms/static/src/js/views/search_panel.esm.js +1 -5
- odoo/addons/dms/static/src/models/attachment.esm.js +0 -2
- odoo/addons/dms/static/src/models/attachment_image.esm.js +0 -2
- odoo/addons/dms/static/src/models/attachment_viewer_viewable.esm.js +0 -2
- odoo/addons/dms/static/tests/tours/dms_portal_tour.esm.js +3 -7
- odoo/addons/dms/template/portal.xml +8 -6
- odoo/addons/dms/tests/common.py +9 -10
- odoo/addons/dms/tests/test_benchmark.py +19 -1
- odoo/addons/dms/tests/test_directory.py +8 -5
- odoo/addons/dms/tests/test_file_database.py +1 -1
- odoo/addons/dms/tests/test_portal.py +16 -17
- odoo/addons/dms/views/dms_access_groups_views.xml +13 -13
- odoo/addons/dms/views/dms_category.xml +5 -5
- odoo/addons/dms/views/dms_directory.xml +101 -110
- odoo/addons/dms/views/dms_file.xml +66 -84
- odoo/addons/dms/views/dms_tag.xml +14 -33
- odoo/addons/dms/views/menu.xml +22 -13
- odoo/addons/dms/views/storage.xml +189 -193
- odoo/addons/dms/wizards/wizard_dms_file_move_views.xml +1 -1
- {odoo_addon_dms-17.0.1.2.0.dist-info → odoo_addon_dms-18.0.1.0.0.2.dist-info}/METADATA +72 -65
- {odoo_addon_dms-17.0.1.2.0.dist-info → odoo_addon_dms-18.0.1.0.0.2.dist-info}/RECORD +56 -59
- odoo/addons/dms/static/src/scss/directory_kanban.scss +0 -53
- odoo/addons/dms/static/src/scss/dms_common.scss +0 -69
- odoo/addons/dms/static/src/scss/file_kanban.scss +0 -70
- {odoo_addon_dms-17.0.1.2.0.dist-info → odoo_addon_dms-18.0.1.0.0.2.dist-info}/WHEEL +0 -0
- {odoo_addon_dms-17.0.1.2.0.dist-info → odoo_addon_dms-18.0.1.0.0.2.dist-info}/top_level.txt +0 -0
@@ -367,9 +367,9 @@ ul.auto-toc {
|
|
367
367
|
!! This file is generated by oca-gen-addon-readme !!
|
368
368
|
!! changes will be overwritten. !!
|
369
369
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
370
|
-
!! source digest: sha256:
|
370
|
+
!! source digest: sha256:904150d6b7037648a3ed02450c9b27d802f4cee614b59b1fa582f48093e1a0ed
|
371
371
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
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/dms/tree/
|
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/dms/tree/18.0/dms"><img alt="OCA/dms" src="https://img.shields.io/badge/github-OCA%2Fdms-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/dms-18-0/dms-18-0-dms"><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/dms&target_branch=18.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
|
373
373
|
<p>DMS is a module for creating, managing and viewing document files
|
374
374
|
directly within Odoo. This module is only the basis for an entire
|
375
375
|
ecosystem of apps that extend and seamlessly integrate with the document
|
@@ -444,8 +444,8 @@ Access Groups</em>.<ul>
|
|
444
444
|
<li>Create a new group, name it appropriately, and turn on all three
|
445
445
|
permissions (Create, Write and Unlink. Read is implied and always
|
446
446
|
enabled).</li>
|
447
|
-
<li>Add any other top-level administrative users to the group if
|
448
|
-
|
447
|
+
<li>Add any other top-level administrative users to the group if needed
|
448
|
+
(your user should already be there).</li>
|
449
449
|
<li>You can create other groups in here later for fine-grained access
|
450
450
|
control.</li>
|
451
451
|
</ul>
|
@@ -534,6 +534,9 @@ secrets, remember to forbid access to the secrets fields by other
|
|
534
534
|
means. It would be nice to be able to remove that rule at some point.</li>
|
535
535
|
<li>Searchpanel in files: Highlight items (shading) without records when
|
536
536
|
filtering something (by name for example).</li>
|
537
|
+
<li>Accessing the clipboard (for example copy share link of
|
538
|
+
file/directory) is limited to secure connections. It also happens in
|
539
|
+
any part of Odoo.</li>
|
537
540
|
</ul>
|
538
541
|
</div>
|
539
542
|
<div class="section" id="bug-tracker">
|
@@ -541,7 +544,7 @@ filtering something (by name for example).</li>
|
|
541
544
|
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/dms/issues">GitHub Issues</a>.
|
542
545
|
In case of trouble, please check there if your issue has already been reported.
|
543
546
|
If you spotted it first, help us to smash it by providing a detailed and welcomed
|
544
|
-
<a class="reference external" href="https://github.com/OCA/dms/issues/new?body=module:%20dms%0Aversion:%
|
547
|
+
<a class="reference external" href="https://github.com/OCA/dms/issues/new?body=module:%20dms%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
|
545
548
|
<p>Do not contact contributors directly about support or help with technical issues.</p>
|
546
549
|
</div>
|
547
550
|
<div class="section" id="credits">
|
@@ -576,6 +579,10 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
|
|
576
579
|
<li>Timothée Vannier <<a class="reference external" href="mailto:tva@subteno.com">tva@subteno.com</a>></li>
|
577
580
|
</ul>
|
578
581
|
</li>
|
582
|
+
<li><a class="reference external" href="https://www.kencove.com">Kencove</a>:<ul>
|
583
|
+
<li>Mohamed Alkobrosli <<a class="reference external" href="mailto:malkobrosly@kencove.com">malkobrosly@kencove.com</a>></li>
|
584
|
+
</ul>
|
585
|
+
</li>
|
579
586
|
</ul>
|
580
587
|
</div>
|
581
588
|
<div class="section" id="other-credits">
|
@@ -598,7 +605,7 @@ DMS icon</li>
|
|
598
605
|
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
|
599
606
|
mission is to support the collaborative development of Odoo features and
|
600
607
|
promote its widespread use.</p>
|
601
|
-
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/dms/tree/
|
608
|
+
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/dms/tree/18.0/dms">OCA/dms</a> project on GitHub.</p>
|
602
609
|
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
|
603
610
|
</div>
|
604
611
|
</div>
|
@@ -1,10 +1,9 @@
|
|
1
|
-
/** @odoo-module **/
|
2
|
-
|
3
1
|
// /** ********************************************************************************
|
4
2
|
// Copyright 2024 Subteno - Timothée Vannier (https://www.subteno.com).
|
5
3
|
// License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
6
4
|
// **********************************************************************************/
|
7
5
|
import {Component, onWillUpdateProps} from "@odoo/owl";
|
6
|
+
import {_t} from "@web/core/l10n/translation";
|
8
7
|
import {registry} from "@web/core/registry";
|
9
8
|
import {standardFieldProps} from "@web/views/fields/standard_field_props";
|
10
9
|
import {useService} from "@web/core/utils/hooks";
|
@@ -24,10 +23,11 @@ class DmsPathField extends Component {
|
|
24
23
|
|
25
24
|
_onNodeClicked(event) {
|
26
25
|
event.preventDefault();
|
26
|
+
const target = event.currentTarget;
|
27
27
|
this.action.doAction({
|
28
28
|
type: "ir.actions.act_window",
|
29
|
-
res_model:
|
30
|
-
res_id:
|
29
|
+
res_model: target.getAttribute("data-model"),
|
30
|
+
res_id: Number(target.getAttribute("data-id")),
|
31
31
|
views: [[false, "form"]],
|
32
32
|
target: "current",
|
33
33
|
context: {},
|
@@ -42,7 +42,7 @@ DmsPathField.props = {
|
|
42
42
|
|
43
43
|
const dmsPathField = {
|
44
44
|
component: DmsPathField,
|
45
|
-
|
45
|
+
displayName: _t("Dms Path Field"),
|
46
46
|
supportedTypes: ["text"],
|
47
47
|
extractProps: () => {
|
48
48
|
return {};
|
@@ -1,10 +1,9 @@
|
|
1
|
-
/** @odoo-module **/
|
2
|
-
|
3
1
|
// /** ********************************************************************************
|
4
2
|
// Copyright 2024 Subteno - Timothée Vannier (https://www.subteno.com).
|
5
3
|
// License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
6
4
|
// **********************************************************************************/
|
7
5
|
import {BinaryField} from "@web/views/fields/binary/binary_field";
|
6
|
+
import {_t} from "@web/core/l10n/translation";
|
8
7
|
import {registry} from "@web/core/registry";
|
9
8
|
import {standardFieldProps} from "@web/views/fields/standard_field_props";
|
10
9
|
import {useFileViewer} from "@web/core/file_viewer/file_viewer_hook";
|
@@ -37,8 +36,7 @@ PreviewRecordField.props = {
|
|
37
36
|
|
38
37
|
const previewRecordField = {
|
39
38
|
component: PreviewRecordField,
|
40
|
-
|
41
|
-
display_name: "Preview Record",
|
39
|
+
displayName: _t("Preview Record"),
|
42
40
|
supportedTypes: ["binary"],
|
43
41
|
extractProps: () => {
|
44
42
|
return {};
|
@@ -1,15 +1,12 @@
|
|
1
|
-
/** @odoo-module */
|
2
|
-
|
3
1
|
// /** ********************************************************************************
|
4
2
|
// Copyright 2024 Subteno - Timothée Vannier (https://www.subteno.com).
|
5
3
|
// License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
6
4
|
// **********************************************************************************/
|
7
5
|
|
8
6
|
import {useBus, useService} from "@web/core/utils/hooks";
|
7
|
+
import {useEffect, useRef, useState} from "@odoo/owl";
|
9
8
|
import {_t} from "@web/core/l10n/translation";
|
10
9
|
|
11
|
-
const {useRef, useEffect, useState} = owl;
|
12
|
-
|
13
10
|
export function createFileDropZoneExtension() {
|
14
11
|
return {
|
15
12
|
setup() {
|
@@ -36,7 +33,7 @@ export function createFileDropZoneExtension() {
|
|
36
33
|
el.removeEventListener("drop", drop);
|
37
34
|
};
|
38
35
|
},
|
39
|
-
|
36
|
+
// eslint-disable-next-line no-undef
|
40
37
|
() => [document.querySelector(".o_content")]
|
41
38
|
);
|
42
39
|
},
|
@@ -1,12 +1,10 @@
|
|
1
|
-
/** @odoo-module **/
|
2
1
|
/* Copyright 2021-2024 Tecnativa - Víctor Martínez
|
3
2
|
* Copyright 2024 Subteno - Timothée Vannier (https://www.subteno.com).
|
4
3
|
* License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */
|
5
4
|
|
6
5
|
import {SearchModel} from "@web/search/search_model";
|
7
|
-
import {registry} from "@web/core/registry";
|
8
6
|
|
9
|
-
class DMSSearchPanel extends SearchModel {
|
7
|
+
export class DMSSearchPanel extends SearchModel {
|
10
8
|
_getCategoryDomain(excludedCategoryId) {
|
11
9
|
const domain = super._getCategoryDomain(...arguments);
|
12
10
|
for (const category of this.categories) {
|
@@ -24,5 +22,3 @@ class DMSSearchPanel extends SearchModel {
|
|
24
22
|
return domain;
|
25
23
|
}
|
26
24
|
}
|
27
|
-
|
28
|
-
registry.category("views").add("dms_search_panel", DMSSearchPanel);
|
@@ -1,5 +1,3 @@
|
|
1
|
-
/** @odoo-module **/
|
2
|
-
|
3
1
|
// /** ********************************************************************************
|
4
2
|
// Copyright 2024 Subteno - Timothée Vannier (https://www.subteno.com).
|
5
3
|
// License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
@@ -12,12 +10,11 @@ registry.category("web_tour.tours").add("dms_portal_mail_tour", {
|
|
12
10
|
steps: () => [
|
13
11
|
{
|
14
12
|
content: "Go to Mails directory",
|
15
|
-
extra_trigger: "li.breadcrumb-item:contains('Documents')",
|
16
13
|
trigger: ".tr_dms_directory_link:contains('Mails')",
|
14
|
+
run: "click",
|
17
15
|
},
|
18
16
|
{
|
19
17
|
content: "Go to Mail_01.eml",
|
20
|
-
extra_trigger: "li.breadcrumb-item:contains('Mails')",
|
21
18
|
trigger: ".tr_dms_file_link:contains('Mail_01.eml')",
|
22
19
|
},
|
23
20
|
],
|
@@ -29,17 +26,16 @@ registry.category("web_tour.tours").add("dms_portal_partners_tour", {
|
|
29
26
|
steps: () => [
|
30
27
|
{
|
31
28
|
content: "Go to Partners directory",
|
32
|
-
extra_trigger: "li.breadcrumb-item:contains('Documents')",
|
33
29
|
trigger: ".tr_dms_directory_link:contains('Partners')",
|
30
|
+
run: "click",
|
34
31
|
},
|
35
32
|
{
|
36
33
|
content: "Go to Joel Willis",
|
37
|
-
extra_trigger: "li.breadcrumb-item:contains('Partners')",
|
38
34
|
trigger: ".tr_dms_directory_link:contains('Joel Willis')",
|
35
|
+
run: "click",
|
39
36
|
},
|
40
37
|
{
|
41
38
|
content: "Go to test.txt",
|
42
|
-
extra_trigger: "li.breadcrumb-item:contains('Joel Willis')",
|
43
39
|
trigger: ".tr_dms_file_link:contains('test.txt')",
|
44
40
|
},
|
45
41
|
],
|
@@ -10,8 +10,8 @@
|
|
10
10
|
inherit_id="portal.portal_my_home"
|
11
11
|
priority="20"
|
12
12
|
>
|
13
|
-
<
|
14
|
-
<div class="
|
13
|
+
<div id="portal_common_category" position="after">
|
14
|
+
<div class="o_portal_category row g-2 mt-3" id="portal_dms_category">
|
15
15
|
<t t-call="portal.portal_docs_entry">
|
16
16
|
<t t-set="title">Documents</t>
|
17
17
|
<t t-set="text" t-value="'Manage your documents'" />
|
@@ -23,7 +23,7 @@
|
|
23
23
|
<t t-set="placeholder_count" t-value="'dms_directory_count'" />
|
24
24
|
</t>
|
25
25
|
</div>
|
26
|
-
</
|
26
|
+
</div>
|
27
27
|
</template>
|
28
28
|
<template
|
29
29
|
id="portal_my_dms_breadcrumbs"
|
@@ -43,7 +43,9 @@
|
|
43
43
|
</li>
|
44
44
|
</t>
|
45
45
|
<t t-foreach="dms_parent_categories" t-as="dms_parent_category">
|
46
|
-
<li
|
46
|
+
<li
|
47
|
+
t-attf-class="breadcrumb-item #{'active 'if not dms_directory else ''}"
|
48
|
+
>
|
47
49
|
<t t-if="dms_parent_category.id != dms_directory.id">
|
48
50
|
<a
|
49
51
|
t-attf-href="/my/dms/directory/#{dms_parent_category.id}?{{ keep_query() }}"
|
@@ -52,7 +54,7 @@
|
|
52
54
|
<span t-esc="dms_parent_category.name" />
|
53
55
|
</a>
|
54
56
|
</t>
|
55
|
-
<t t-
|
57
|
+
<t t-else="">
|
56
58
|
<span t-esc="dms_parent_category.name" />
|
57
59
|
</t>
|
58
60
|
</li>
|
@@ -115,7 +117,7 @@
|
|
115
117
|
class="o_portal_contact_img"
|
116
118
|
t-att-src="dms_file.icon_url + (('&access_token=' + access_token) if access_token else '')"
|
117
119
|
/>
|
118
|
-
|
120
|
+
<span t-esc="dms_file.name" />
|
119
121
|
</a>
|
120
122
|
</td>
|
121
123
|
<td>
|
odoo/addons/dms/tests/common.py
CHANGED
@@ -32,21 +32,20 @@ def track_function(
|
|
32
32
|
threading.current_thread().query_count = 0
|
33
33
|
threading.current_thread().perf_t0 = time.time()
|
34
34
|
result = func(*args, **kwargs)
|
35
|
-
message = "
|
35
|
+
message = f"{func.__name__}"
|
36
36
|
if args and hasattr(args[0], "uid"):
|
37
|
-
message = " (
|
37
|
+
message = f" ({args[0].uid})"
|
38
38
|
if hasattr(threading.current_thread(), "query_count"):
|
39
39
|
query_count = threading.current_thread().query_count
|
40
40
|
query_time = threading.current_thread().query_time
|
41
41
|
perf_t0 = threading.current_thread().perf_t0
|
42
42
|
remaining_time = time.time() - perf_t0 - query_time
|
43
43
|
time_taken = query_time + remaining_time
|
44
|
-
message +=
|
45
|
-
query_count
|
46
|
-
|
47
|
-
remaining_time,
|
48
|
-
time_taken,
|
44
|
+
message += (
|
45
|
+
f" - {query_count} Q {query_time:.3f}s"
|
46
|
+
f"QT {remaining_time:.3f}s OT {time_taken:.3f}s TT"
|
49
47
|
)
|
48
|
+
|
50
49
|
tracking_parameters += [
|
51
50
|
query_count,
|
52
51
|
query_time,
|
@@ -54,13 +53,13 @@ def track_function(
|
|
54
53
|
time_taken,
|
55
54
|
]
|
56
55
|
if max_query_count and query_count > max_query_count:
|
57
|
-
raise AssertionError("More than
|
56
|
+
raise AssertionError(f"More than {max_query_count} queries")
|
58
57
|
if max_query_time and query_time > max_query_time:
|
59
58
|
raise AssertionError(
|
60
|
-
"Queries took longer than
|
59
|
+
f"Queries took longer than {max_query_time:.3f}s"
|
61
60
|
)
|
62
61
|
if max_time and time_taken > max_time:
|
63
|
-
raise AssertionError("Function took longer than
|
62
|
+
raise AssertionError("Function took longer than {max_time:.3f}s")
|
64
63
|
if not return_tracking:
|
65
64
|
_logger.info(message)
|
66
65
|
if return_tracking:
|
@@ -3,19 +3,37 @@
|
|
3
3
|
# Copyright 2024 Subteno - Timothée Vannier (https://www.subteno.com).
|
4
4
|
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
5
5
|
|
6
|
+
import cProfile
|
6
7
|
import logging
|
7
8
|
import os
|
8
9
|
import unittest
|
10
|
+
import warnings
|
11
|
+
from functools import wraps
|
9
12
|
|
10
13
|
from odoo.tests import common, tagged
|
11
14
|
from odoo.tools import convert_file
|
12
|
-
from odoo.tools.misc import profile
|
13
15
|
|
14
16
|
from .common import track_function
|
15
17
|
|
16
18
|
_logger = logging.getLogger(__name__)
|
17
19
|
|
18
20
|
|
21
|
+
class profile:
|
22
|
+
def __init__(self, fname=None):
|
23
|
+
warnings.warn("Since 16.0.", DeprecationWarning, stacklevel=2)
|
24
|
+
self.fname = fname
|
25
|
+
|
26
|
+
def __call__(self, f):
|
27
|
+
@wraps(f)
|
28
|
+
def wrapper(*args, **kwargs):
|
29
|
+
profile = cProfile.Profile()
|
30
|
+
result = profile.runcall(f, *args, **kwargs)
|
31
|
+
profile.dump_stats(self.fname or (f"{f.__name__}.cprof"))
|
32
|
+
return result
|
33
|
+
|
34
|
+
return wrapper
|
35
|
+
|
36
|
+
|
19
37
|
# This tests will only be executed if --test-tags benchmark is defined
|
20
38
|
@tagged("-standard", "benchmark")
|
21
39
|
class BenchmarkTestCase(common.TransactionCase):
|
@@ -87,7 +87,7 @@ class DirectoryTestCaseBase(StorageDatabaseBaseCase):
|
|
87
87
|
@users("dms-manager", "dms-user")
|
88
88
|
def test_rename_directory(self):
|
89
89
|
path_names = self.subdirectory.complete_name
|
90
|
-
self.directory.write({"name": "New Test Name
|
90
|
+
self.directory.write({"name": f"New Test Name {self.env.user.login}"})
|
91
91
|
self.assertNotEqual(
|
92
92
|
path_names,
|
93
93
|
self.subdirectory.complete_name,
|
@@ -273,13 +273,13 @@ class DirectoryMailTestCase(StorageDatabaseBaseCase):
|
|
273
273
|
super().setUpClass()
|
274
274
|
cls.params = cls.env["ir.config_parameter"].sudo()
|
275
275
|
cls.params.set_param("mail.catchall.domain", "dmstest.com")
|
276
|
-
domain = cls.env["mail.alias.domain"].create({"name": "dmstest.com"})
|
277
|
-
cls.env["mail.alias"].create(
|
276
|
+
cls.domain = cls.env["mail.alias.domain"].create({"name": "dmstest.com"})
|
277
|
+
cls.alias = cls.env["mail.alias"].create(
|
278
278
|
{
|
279
279
|
"alias_model_id": cls.env["ir.model"]
|
280
280
|
.search([("model", "=", "dms.directory")])
|
281
281
|
.id,
|
282
|
-
"alias_domain_id": domain.id,
|
282
|
+
"alias_domain_id": cls.domain.id,
|
283
283
|
}
|
284
284
|
)
|
285
285
|
|
@@ -299,4 +299,7 @@ class DirectoryMailTestCase(StorageDatabaseBaseCase):
|
|
299
299
|
self.directory.write(
|
300
300
|
{"alias_process": "directory", "alias_name": "directory+test"}
|
301
301
|
)
|
302
|
-
self.
|
302
|
+
self.assertEqual(
|
303
|
+
self.directory.alias_id.display_name,
|
304
|
+
f"{self.directory.alias_name}@{self.domain.name}",
|
305
|
+
)
|
@@ -52,7 +52,7 @@ class FileDatabaseTestCase(StorageDatabaseBaseCase):
|
|
52
52
|
def test_rename_file(self):
|
53
53
|
file = self.create_file(directory=self.directory)
|
54
54
|
extension = file.extension
|
55
|
-
file.write({"name": "test
|
55
|
+
file.write({"name": f"test-{self.env.user.login}.jpg"})
|
56
56
|
self.assertNotEqual(file.extension, extension, "Extension should be different")
|
57
57
|
|
58
58
|
@users("dms-manager", "dms-user")
|
@@ -1,9 +1,10 @@
|
|
1
|
-
# Copyright 2021-
|
1
|
+
# Copyright 2021-2025 Tecnativa - Víctor Martínez
|
2
2
|
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl)
|
3
3
|
|
4
4
|
import odoo.tests
|
5
5
|
from odoo.exceptions import AccessError
|
6
6
|
from odoo.tests.common import users
|
7
|
+
from odoo.tools import mute_logger
|
7
8
|
|
8
9
|
from .common import StorageAttachmentBaseCase
|
9
10
|
|
@@ -15,9 +16,6 @@ class TestDmsPortal(odoo.tests.HttpCase, StorageAttachmentBaseCase):
|
|
15
16
|
super().setUpClass()
|
16
17
|
cls.partner = cls.env.ref("base.partner_demo_portal")
|
17
18
|
cls.portal_user = cls.partner.user_ids
|
18
|
-
cls.other_portal_user = cls.other_partner.user_ids
|
19
|
-
cls.portal_user.login = "portal"
|
20
|
-
cls.other_portal_user.login = "other_portal"
|
21
19
|
cls._create_attachment("test.txt")
|
22
20
|
cls._create_attachment("test2.txt", cls.other_partner)
|
23
21
|
cls.directory_partner = cls._get_partner_directory()
|
@@ -29,7 +27,7 @@ class TestDmsPortal(odoo.tests.HttpCase, StorageAttachmentBaseCase):
|
|
29
27
|
self.authenticate("portal", "portal")
|
30
28
|
# 404: Incorrect access_token
|
31
29
|
file_text = self.create_file(directory=self.directory_partner)
|
32
|
-
url = "
|
30
|
+
url = f"{file_text.access_url}&access_token=abc-def"
|
33
31
|
response = self.url_open(url, timeout=20)
|
34
32
|
self.assertEqual(
|
35
33
|
response.status_code, 404, "Can't access file with incorrect access_token"
|
@@ -51,41 +49,42 @@ class TestDmsPortal(odoo.tests.HttpCase, StorageAttachmentBaseCase):
|
|
51
49
|
self.start_tour("/my", tour, login="portal")
|
52
50
|
|
53
51
|
@users("portal")
|
52
|
+
@mute_logger("odoo.addons.base.models.ir_rule")
|
54
53
|
def test_permission_portal_user_access_own_attachment(self):
|
55
54
|
"""
|
56
55
|
The user can access its own attachments, even if its access group are not set
|
57
56
|
"""
|
58
57
|
# Has to manually su=False because the portal user is not a superuser,
|
59
58
|
# but odoo uses somewhere sudo() internally
|
60
|
-
file = self.file_partner.with_user(self.
|
61
|
-
|
62
|
-
)
|
63
|
-
directory = self.directory_partner.with_user(self.portal_user).with_env(
|
59
|
+
file = self.file_partner.with_user(self.env.user).with_env(self.env(su=False))
|
60
|
+
directory = self.directory_partner.with_user(self.env.user).with_env(
|
64
61
|
self.env(su=False)
|
65
62
|
)
|
66
63
|
# Portal user can only read
|
67
|
-
file.
|
64
|
+
file.check_access("read")
|
68
65
|
|
69
66
|
# Portal user can't do anything else
|
70
67
|
with self.assertRaises(AccessError, msg="Portal user should not have access"):
|
71
|
-
file.
|
72
|
-
file.
|
73
|
-
directory.
|
68
|
+
file.check_access("write")
|
69
|
+
file.check_access("unlink")
|
70
|
+
directory.check_access("create")
|
74
71
|
|
75
72
|
@users("portal")
|
73
|
+
@mute_logger("odoo.addons.base.models.ir_rule")
|
76
74
|
def test_permission_portal_user_access_other_attachment(self):
|
77
75
|
"""
|
78
76
|
The user can't access other attachments if its access group are not set
|
79
77
|
"""
|
80
78
|
# Has to manually su=False because the portal user is not a superuser,
|
81
79
|
# but odoo uses somewhere sudo() internally
|
82
|
-
file = self.other_file_partner.with_user(self.
|
80
|
+
file = self.other_file_partner.with_user(self.env.user).with_env(
|
83
81
|
self.env(su=False)
|
84
82
|
)
|
83
|
+
# file.invalidate_recordset()
|
85
84
|
# Portal user can't do anything
|
86
85
|
with self.assertRaises(AccessError, msg="Portal user should not have access"):
|
87
|
-
file.
|
86
|
+
file.check_access("read")
|
88
87
|
with self.assertRaises(AccessError, msg="Portal user should not have access"):
|
89
|
-
file.
|
88
|
+
file.check_access("write")
|
90
89
|
with self.assertRaises(AccessError, msg="Portal user should not have access"):
|
91
|
-
file.
|
90
|
+
file.check_access("unlink")
|
@@ -8,17 +8,17 @@
|
|
8
8
|
-->
|
9
9
|
<odoo>
|
10
10
|
<record id="view_dms_access_groups_tree" model="ir.ui.view">
|
11
|
-
<field name="name">dms_access_groups.
|
11
|
+
<field name="name">dms_access_groups.list</field>
|
12
12
|
<field name="model">dms.access.group</field>
|
13
13
|
<field name="arch" type="xml">
|
14
|
-
<
|
14
|
+
<list>
|
15
15
|
<field name="name" />
|
16
16
|
<field name="perm_create" />
|
17
17
|
<field name="perm_write" />
|
18
18
|
<field name="perm_unlink" />
|
19
19
|
<field name="count_users" />
|
20
20
|
<field name="count_directories" />
|
21
|
-
</
|
21
|
+
</list>
|
22
22
|
</field>
|
23
23
|
</record>
|
24
24
|
<record id="view_dms_access_groups_form" model="ir.ui.view">
|
@@ -53,41 +53,41 @@
|
|
53
53
|
<notebook>
|
54
54
|
<page name="users" string="Users">
|
55
55
|
<field name="users">
|
56
|
-
<
|
56
|
+
<list>
|
57
57
|
<field name="name" />
|
58
58
|
<field name="login" />
|
59
59
|
<field name="lang" />
|
60
60
|
<field name="login_date" />
|
61
|
-
</
|
61
|
+
</list>
|
62
62
|
</field>
|
63
63
|
</page>
|
64
64
|
<page name="groups" string="Groups">
|
65
65
|
<field name="group_ids">
|
66
|
-
<
|
66
|
+
<list>
|
67
67
|
<field name="name" />
|
68
68
|
<field name="comment" />
|
69
|
-
</
|
69
|
+
</list>
|
70
70
|
</field>
|
71
71
|
</page>
|
72
72
|
<page name="extra_users" string="Explicit Users">
|
73
73
|
<field name="explicit_user_ids">
|
74
|
-
<
|
74
|
+
<list>
|
75
75
|
<field name="name" />
|
76
76
|
<field name="login" />
|
77
77
|
<field name="lang" />
|
78
78
|
<field name="login_date" />
|
79
|
-
</
|
79
|
+
</list>
|
80
80
|
</field>
|
81
81
|
</page>
|
82
82
|
<page name="childs" string="Child Groups">
|
83
83
|
<field name="child_group_ids">
|
84
|
-
<
|
84
|
+
<list>
|
85
85
|
<field name="name" />
|
86
86
|
<field name="perm_create" />
|
87
87
|
<field name="perm_write" />
|
88
88
|
<field name="perm_unlink" />
|
89
89
|
<field name="count_users" />
|
90
|
-
</
|
90
|
+
</list>
|
91
91
|
</field>
|
92
92
|
</page>
|
93
93
|
<page string="Directories">
|
@@ -101,11 +101,11 @@
|
|
101
101
|
<record id="action_dms_access_groups" model="ir.actions.act_window">
|
102
102
|
<field name="name">Access Groups</field>
|
103
103
|
<field name="res_model">dms.access.group</field>
|
104
|
-
<field name="view_mode">
|
104
|
+
<field name="view_mode">list,form</field>
|
105
105
|
<field
|
106
106
|
name="view_ids"
|
107
107
|
eval="[(5, 0, 0),
|
108
|
-
(0, 0, {'view_mode': '
|
108
|
+
(0, 0, {'view_mode': 'list', 'view_id': ref('view_dms_access_groups_tree')}),
|
109
109
|
(0, 0, {'view_mode': 'form', 'view_id': ref('view_dms_access_groups_form')})]"
|
110
110
|
/>
|
111
111
|
</record>
|