Skip to content
Closed
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
3 changes: 3 additions & 0 deletions dms/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ and their files. Another possibility is to click on "Share" button
inside a directory or a file for obtaining a tokenized link for single
access to that resource, no matter if logged or not.

For any file if you add the portal user or the internal user to
followers mixin, they can read that file.

Known issues / Roadmap
======================

Expand Down
6 changes: 3 additions & 3 deletions dms/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
"template/portal.xml",
# Data
"data/onboarding_data.xml",
# Wizard
"wizards/wizard_dms_file_move_views.xml",
"wizards/wizard_dms_share_views.xml",
# Views
"views/dms_tag.xml",
"views/dms_category.xml",
Expand All @@ -37,9 +40,6 @@
"views/dms_access_groups_views.xml",
"views/res_config_settings.xml",
"views/menu.xml",
# Wizard
"wizards/wizard_dms_file_move_views.xml",
"wizards/wizard_dms_share_views.xml",
],
"assets": {
"web.assets_backend": [
Expand Down
15 changes: 14 additions & 1 deletion dms/controllers/portal.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,11 @@ def _get_files(self, access_token, dms_directory_id, search, search_in, sort_br)
file_domain = [
("is_hidden", "=", False),
("directory_id", "=", dms_directory_id),
(
"message_partner_ids",
"child_of",
[request.env.user.commercial_partner_id.id],
),
]
# search
if search and search_in == "name":
Expand Down Expand Up @@ -206,7 +211,15 @@ def _get_directories(
:rtype: tuple[odoo.model.dms_directory, bool|odoo.model.dms_directory]
"""
# domain
domain = [("is_hidden", "=", False), ("parent_id", "=", dms_directory_id)]
domain = [
("is_hidden", "=", False),
("parent_id", "=", dms_directory_id),
(
"file_ids.message_partner_ids",
"child_of",
[request.env.user.commercial_partner_id.id],
),
]
# search
if search and search_in:
domain.append(("name", "ilike", search))
Expand Down
2 changes: 2 additions & 0 deletions dms/readme/USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ group in directories, so they will see in the portal such directories
and their files. Another possibility is to click on "Share" button
inside a directory or a file for obtaining a tokenized link for single
access to that resource, no matter if logged or not.

For any file if you add the portal user or the internal user to followers mixin, they can read that file.
3 changes: 0 additions & 3 deletions dms/security/ir.model.access.csv
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,14 @@ access_dms_storage_portal,dms_storage_portal,model_dms_storage,base.group_portal
access_dms_storage_user,dms_storage_user,model_dms_storage,group_dms_user,1,0,0,0
access_dms_storage_manager,dms_storage_manager,model_dms_storage,group_dms_manager,1,1,1,1

access_dms_directory_public,dms_directory_public,model_dms_directory,base.group_public,1,0,0,0
access_dms_directory_portal,dms_directory_portal,model_dms_directory,base.group_portal,1,0,0,0
access_dms_directory_base_user,dms_directory_base_user,model_dms_directory,base.group_user,1,0,0,0
access_dms_directory_user,dms_directory_user,model_dms_directory,group_dms_user,1,1,1,1

access_dms_file_public,dms_file_public,model_dms_file,base.group_public,1,0,0,0
access_dms_file_portal,dms_file_portal,model_dms_file,base.group_portal,1,0,0,0
access_dms_file_base_user,dms_file_base_user,model_dms_file,base.group_user,1,0,0,0
access_dms_file_user,dms_file_user,model_dms_file,group_dms_user,1,1,1,1

access_dms_access_group_public,access_dms_access_group_public,model_dms_access_group,base.group_public,1,0,0,0
access_dms_access_group_portal,access_dms_access_group_portal,model_dms_access_group,base.group_portal,1,0,0,0
access_security_access_groups_user,access_security_access_groups_user,model_dms_access_group,base.group_user,1,0,0,0
access_security_access_groups_dms_user,access_security_access_groups_dms_user,model_dms_access_group,group_dms_user,1,1,1,1
Expand Down
133 changes: 50 additions & 83 deletions dms/security/security.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<record id="group_dms_user" model="res.groups">
<field name="name">User</field>
<field name="category_id" ref="category_dms_security" />
<field name="implied_ids" eval="[(4, ref('base.group_user'))]" />
<field name="implied_ids" eval="[(4, ref('base.group_erp_manager'))]" />
</record>
<record id="group_dms_manager" model="res.groups">
<field name="name">Manager</field>
Expand All @@ -29,31 +29,46 @@
<record id="rule_multi_company_storage" model="ir.rule">
<field name="name">DMS Storage multi-company</field>
<field name="model_id" ref="model_dms_storage" />
<field name="global" eval="True" />
<field name="global" eval="False" />
<field name="groups" eval="[(4, ref('group_dms_user'))]" />
<field name="perm_read" eval="1" />
<field name="perm_create" eval="0" />
<field name="perm_write" eval="0" />
<field name="perm_unlink" eval="0" />
<field
name="domain_force"
>['|',('company_id','=',False),('company_id','in',company_ids)]</field>
</record>
<record id="rule_multi_company_directory" model="ir.rule">
<field name="name">DMS Directory multi-company</field>
<field name="model_id" ref="model_dms_directory" />
<field name="global" eval="True" />
<field name="global" eval="False" />
<field name="groups" eval="[(4, ref('group_dms_user'))]" />
<field name="perm_read" eval="1" />
<field name="perm_create" eval="0" />
<field name="perm_write" eval="0" />
<field name="perm_unlink" eval="0" />
<field
name="domain_force"
>['|',('company_id','=',False),('company_id','in',company_ids)]</field>
</record>
<record id="rule_multi_company_file" model="ir.rule">
<field name="name">File multi-company</field>
<field name="model_id" ref="model_dms_file" />
<field name="global" eval="True" />
<field name="global" eval="False" />
<field name="groups" eval="[(4, ref('group_dms_user'))]" />
<field name="perm_read" eval="1" />
<field name="perm_create" eval="0" />
<field name="perm_write" eval="0" />
<field name="perm_unlink" eval="0" />
<field
name="domain_force"
>['|',('company_id','=',False),('company_id','in',company_ids)]</field>
</record>
<record id="rule_file_locked" model="ir.rule">
<field name="name">Locked files are only modified by locker user.</field>
<field name="model_id" ref="model_dms_file" />
<field name="groups" eval="[(4, ref('base.group_user'))]" />
<field name="groups" eval="[(4, ref('dms.group_dms_user'))]" />
<field name="global" eval="True" />
<field name="perm_read" eval="0" />
<field name="perm_create" eval="1" />
Expand Down Expand Up @@ -107,85 +122,37 @@
<field name="perm_unlink" eval="1" />
<field name="domain_force">[('is_hidden', '=', True)]</field>
</record>
<!-- These rules leverage computed permission management -->
<record id="rule_directory_computed_create" model="ir.rule">
<field name="name">Apply computed create permissions.</field>
<!-- Portal/Base Users Access Rules -->
<record id="portal_rule_directory_computed_read" model="ir.rule">
<field name="name">Portal Personal Directories Read</field>
<field name="model_id" ref="model_dms_directory" />
<field name="global" eval="True" />
<field name="perm_read" eval="0" />
<field name="perm_create" eval="1" />
<field name="perm_write" eval="0" />
<field name="perm_unlink" eval="0" />
<field name="domain_force">[('permission_create', '=', user.id)]</field>
</record>
<record id="rule_directory_computed_read" model="ir.rule">
<field name="name">Apply computed read permissions.</field>
<field name="model_id" ref="model_dms_directory" />
<field name="global" eval="True" />
<field name="perm_read" eval="1" />
<field name="perm_create" eval="0" />
<field name="perm_write" eval="0" />
<field name="perm_unlink" eval="0" />
<field name="domain_force">[('permission_read', '=', user.id)]</field>
</record>
<record id="rule_directory_computed_unlink" model="ir.rule">
<field name="name">Apply computed unlink permissions.</field>
<field name="model_id" ref="model_dms_directory" />
<field name="global" eval="True" />
<field name="perm_read" eval="0" />
<field name="perm_create" eval="0" />
<field name="perm_write" eval="0" />
<field name="perm_unlink" eval="1" />
<field name="domain_force">[('permission_unlink', '=', user.id)]</field>
</record>
<record id="rule_directory_computed_write" model="ir.rule">
<field name="name">Apply computed write permissions.</field>
<field name="model_id" ref="model_dms_directory" />
<field name="global" eval="True" />
<field name="perm_read" eval="0" />
<field name="perm_create" eval="0" />
<field name="perm_write" eval="1" />
<field name="perm_unlink" eval="0" />
<field name="domain_force">[('permission_write', '=', user.id)]</field>
</record>
<record id="rule_file_computed_create" model="ir.rule">
<field name="name">Apply computed create permissions.</field>
<field name="model_id" ref="model_dms_file" />
<field name="global" eval="True" />
<field name="perm_read" eval="0" />
<field name="perm_create" eval="1" />
<field name="perm_write" eval="0" />
<field name="perm_unlink" eval="0" />
<field name="domain_force">[('permission_create', '=', user.id)]</field>
</record>
<record id="rule_file_computed_read" model="ir.rule">
<field name="name">Apply computed read permissions.</field>
<field name="model_id" ref="model_dms_file" />
<field name="global" eval="True" />
<field name="perm_read" eval="1" />
<field name="perm_create" eval="0" />
<field name="perm_write" eval="0" />
<field name="perm_unlink" eval="0" />
<field name="domain_force">[('permission_read', '=', user.id)]</field>
</record>
<record id="rule_file_computed_unlink" model="ir.rule">
<field name="name">Apply computed unlink permissions.</field>
<field name="model_id" ref="model_dms_file" />
<field name="global" eval="True" />
<field name="perm_read" eval="0" />
<field name="perm_create" eval="0" />
<field name="perm_write" eval="0" />
<field name="perm_unlink" eval="1" />
<field name="domain_force">[('permission_unlink', '=', user.id)]</field>
</record>
<record id="rule_file_computed_write" model="ir.rule">
<field name="name">Apply computed write permissions.</field>
<field
name="domain_force"
>[('file_ids.message_partner_ids','child_of',[user.commercial_partner_id.id])]</field>
<field
name="groups"
eval="[Command.link(ref('base.group_portal')), Command.link(ref('base.group_user'))]"
/>
<field name="perm_unlink" eval="False" />
<field name="perm_write" eval="False" />
<field name="perm_read" eval="True" />
<field name="perm_create" eval="False" />
</record>
<!-- Portal/Base Users Access Rules -->
<record id="portal_rule_file_computed_read" model="ir.rule">
<field name="name">Portal Personal Files Read</field>
<field name="model_id" ref="model_dms_file" />
<field name="global" eval="True" />
<field name="perm_read" eval="0" />
<field name="perm_create" eval="0" />
<field name="perm_write" eval="1" />
<field name="perm_unlink" eval="0" />
<field name="domain_force">[('permission_write', '=', user.id)]</field>
<field name="global" eval="False" />
<field
name="domain_force"
>[('message_partner_ids','child_of',[user.commercial_partner_id.id])]</field>
<field
name="groups"
eval="[Command.link(ref('base.group_portal')), Command.link(ref('base.group_user'))]"
/>
<field name="perm_unlink" eval="False" />
<field name="perm_write" eval="False" />
<field name="perm_read" eval="True" />
<field name="perm_create" eval="False" />
</record>
</odoo>
2 changes: 2 additions & 0 deletions dms/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,8 @@ <h2><a class="toc-backref" href="#toc-entry-11">Portal functionality</a></h2>
and their files. Another possibility is to click on “Share” button
inside a directory or a file for obtaining a tokenized link for single
access to that resource, no matter if logged or not.</p>
<p>For any file if you add the portal user or the internal user to
followers mixin, they can read that file.</p>
</div>
</div>
<div class="section" id="known-issues-roadmap">
Expand Down
11 changes: 11 additions & 0 deletions dms/tests/test_portal.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,17 @@ def test_access_portal(self):
)

def test_tour(self):
file_id = self.env.ref("dms.file_11_demo")
follower = self.env["mail.followers"].create(
{
"res_model": "dms.file",
"res_id": file_id.id,
"partner_id": self.portal_user.partner_id.id,
"is_active": True,
}
)

file_id.message_follower_ids = follower
for tour in ("dms_portal_mail_tour", "dms_portal_partners_tour"):
with self.subTest(tour=tour):
self.start_tour("/my", tour, login="portal")
Expand Down
7 changes: 7 additions & 0 deletions dms/views/dms_directory.xml
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,13 @@
<field name="arch" type="xml">
<form>
<header>
<button
class="oe_highlight"
name="%(dms.wizard_dms_directory_share_action)d"
type="action"
string="Share"
groups="dms.group_dms_manager"
/>
</header>
<sheet>
<div class="oe_button_box" name="button_box">
Expand Down
9 changes: 9 additions & 0 deletions dms/views/dms_file.xml
Original file line number Diff line number Diff line change
Expand Up @@ -350,13 +350,22 @@
type="object"
string="Lock"
invisible="is_locked or not permission_write"
groups="dms.group_dms_manager"
/>
<button
class="oe_highlight"
name="unlock"
type="object"
string="Unlock"
invisible="not is_locked or not is_lock_editor"
groups="dms.group_dms_manager"
/>
<button
class="oe_highlight"
name="%(dms.wizard_dms_file_share_action)d"
type="action"
string="Share"
groups="dms.group_dms_manager"
/>
</header>
<sheet>
Expand Down
Loading