Skip to content

[19.0][FIX] project_task_default_user: allow portal task creation - #1877

Open
ThiagoMForgeFlow wants to merge 1 commit into
OCA:19.0from
ForgeFlow:19.0-fix-project_task_default_user
Open

ThiagoMForgeFlow wants to merge 1 commit into
OCA:19.0from
ForgeFlow:19.0-fix-project_task_default_user

Conversation

@ThiagoMForgeFlow

@ThiagoMForgeFlow ThiagoMForgeFlow commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

When a portal user creates a task, or changes its stage, the default users are read from the stage/project default_user_ids and written to user_ids. Portal users can't do either: the field domain searches res.groups and user_ids is not portal writable. Both raise AccessError.

Default users are now applied with sudo(), as the core already does in project.task.create for values the portal user can't write. A portal test is added.

Depends on #1875 : the portal test also goes through project_task_code's create, which fails for portal users until that fix is merged.

@ForgeFlow

Default users are read from stages and projects and written to user_ids,
which portal users cannot access, so apply them as superuser.
@OCA-git-bot

Copy link
Copy Markdown
Contributor

Hi @NICO-SOLUTIONS,
some modules you are maintaining are being modified, check this out!

@OCA-git-bot OCA-git-bot added series:19.0 mod:project_task_default_user Module project_task_default_user labels Nov 6, 2026
@NICO-SOLUTIONS

Copy link
Copy Markdown
Member

@ThiagoMForgeFlow
Portal task creation wasn't really in the scope of the module, but hey, it makes sense! I’ll check it ASAP.

@AaronHForgeFlow AaronHForgeFlow left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM when CI is green

@NICO-SOLUTIONS NICO-SOLUTIONS left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ThiagoMForgeFlow

LGTM!
I agree with the approach. Odoo core already uses sudo() for similar operations triggered by portal users, so I don't see a specific security issue here. The actual create() and write() operations are still performed with the original user's permissions.

I tested this from portal and can confirm, that the automatic assignment works as expected and that any direct assignment attempts by the portal user raise an AccessError.

Since the project code fix hasn't been merged yet, we could consider adding the suggested test before merging.

Also, feel free to add yourself to CONTRIBUTORS.md if you’d like!

@@ -1,4 +1,5 @@
from odoo import Command
from odoo.tests import new_test_user

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
from odoo.tests import new_test_user
from odoo.exceptions import AccessError
from odoo.tests import new_test_user

)
self.assertEqual(task.user_ids.ids, [self.user1.id])
task.stage_id = self.stage_with_default
self.assertEqual(task.user_ids.ids, [self.user2.id])

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self.assertEqual(task.user_ids.ids, [self.user2.id])
self.assertEqual(task.user_ids.ids, [self.user2.id])
def test_portal_cannot_assign_users_directly(self):
portal_user = new_test_user(
self.env, login="default_user_portal_security", groups="base.group_portal"
)
self.project_with_default.write(
{
"privacy_visibility": "portal",
"collaborator_ids": [
Command.create({"partner_id": portal_user.partner_id.id})
],
}
)
self.project_with_default.message_subscribe(
partner_ids=portal_user.partner_id.ids
)
Task = (
self.env["project.task"]
.with_user(portal_user)
.with_context(default_project_id=self.project_with_default.id)
)
self.assertFalse(Task._has_field_access(Task._fields["user_ids"], "write"))
with self.assertRaises(AccessError):
Task.create(
{
"name": "Portal task with explicit users",
"user_ids": [Command.set([self.user1.id])],
}
)
task = Task.create(
{"name": "Portal task", "stage_id": self.stage_without_default.id}
)
with self.assertRaises(AccessError):
task.write({"user_ids": [Command.set([self.user1.id])]})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mod:project_task_default_user Module project_task_default_user series:19.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants