Skip to content
Open
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
122 changes: 122 additions & 0 deletions auth_user_role_saml/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
=========================================
360 ERP - Auth User Role SAML glue module
=========================================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:2e6c5776e9b6d22e12988aae8809272a36a5ce9ea7810625ecfa0c5028bac251
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--auth-lightgray.png?logo=github
:target: https://github.com/OCA/server-auth/tree/18.0/auth_user_role_saml
:alt: OCA/server-auth
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/server-auth-18-0/server-auth-18-0-auth_user_role_saml
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/server-auth&target_branch=18.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This is a glue module that bridges ``auth_saml`` and ``auth_user_role``.

It intercepts the standard SAML sign-in process, extracts the identity
payload (attributes) from the SAML response, and passes it to the
generic role evaluation engine. This allows administrators to
automatically provision Odoo roles based on groups or attributes defined
in Azure AD, Keycloak, Okta, or any other SAML 2.0 Identity Provider.

**Table of contents**

.. contents::
:local:

Configuration
=============

To configure SAML role synchronization:

1. Ensure your SAML Identity Provider is configured to send user
attributes (e.g., ``groups``, ``roles``, or ``department``) in its
SAML assertions.
2. Configure your attribute mappings in **Settings > Users & Companies >
Identity Role Mappings** (provided by the base ``auth_user_role``
module).
3. Navigate to **Settings > Users & Companies > SAML Providers** and
open your provider.
4. Under the provider settings, you will find a **Strict Role
Synchronization** checkbox:

- **Unchecked (Default):** Additive mode. Mapped roles are granted,
but manually assigned roles in Odoo are left completely untouched.
- **Checked:** Strict mode. Odoo becomes a strict mirror of the IdP.
Any roles the user possesses in Odoo that are *not* explicitly
granted by the current SAML payload will be automatically removed
upon login.

Usage
=====

Once configured, users simply log in using the SAML Identity Provider
button on the Odoo login screen.

Upon successful authentication, the module will parse the SAML identity
payload, evaluate it against the active mapping rules, and apply the
roles before the user's Odoo session is fully initialized.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/server-auth/issues>`_.
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
`feedback <https://github.com/OCA/server-auth/issues/new?body=module:%20auth_user_role_saml%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
-------

* 360 ERP

Contributors
------------

- Andrea Stirpe

Other credits
-------------

The development of this module has been financially supported by:

- 360 ERP

Maintainers
-----------

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

This module is part of the `OCA/server-auth <https://github.com/OCA/server-auth/tree/18.0/auth_user_role_saml>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
4 changes: 4 additions & 0 deletions auth_user_role_saml/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright 2026 360ERP (<https://www.360erp.com>)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from . import models
15 changes: 15 additions & 0 deletions auth_user_role_saml/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright 2026 360ERP (<https://www.360erp.com>)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

{
"name": "360 ERP - Auth User Role SAML glue module",
"version": "18.0.1.0.0",
"author": "360 ERP, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/server-auth",
"license": "AGPL-3",
"depends": [
"auth_saml",
"auth_user_role",
],
"auto_install": True,
}
5 changes: 5 additions & 0 deletions auth_user_role_saml/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Copyright 2026 360ERP (<https://www.360erp.com>)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from . import res_users
from . import auth_saml_provider
21 changes: 21 additions & 0 deletions auth_user_role_saml/models/auth_saml_provider.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copyright 2026 360ERP (<https://www.360erp.com>)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import fields, models


class AuthSamlProvider(models.Model):
_inherit = "auth.saml.provider"

sync_roles_strictly = fields.Boolean(
string="Strict Role Synchronization",
default=False,
help="If checked, any Odoo roles manually assigned to the user will be removed "
"if they are not explicitly provided by the SAML IdP payload.",
)

def _hook_validate_auth_response(self, response, matching_value):
"""Extract the identity payload before the response object is destroyed."""
vals = super()._hook_validate_auth_response(response, matching_value) or {}
vals["saml_identity_payload"] = response.get_identity()
return vals
35 changes: 35 additions & 0 deletions auth_user_role_saml/models/res_users.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Copyright 2026 360ERP (<https://www.360erp.com>)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

import logging

from odoo import models

_logger = logging.getLogger(__name__)


class ResUser(models.Model):
_inherit = "res.users"

def _auth_saml_signin(self, provider, validation, saml_response):
"""
Intercept the standard SAML sign-in, allow it to complete,
and then pass the identity payload to the generic role engine.
"""
login = super()._auth_saml_signin(provider, validation, saml_response)
identity_payload = validation.get("saml_identity_payload")

if identity_payload is not None:
user = self.env["res.users"].sudo().search([("login", "=", login)], limit=1)

if user:
# Fetch the provider record to check its specific strict_sync setting
provider_record = self.env["auth.saml.provider"].browse(provider)
strict_sync = provider_record.sync_roles_strictly

# Pass strict_sync to the evaluation engine
user.sudo().evaluate_and_apply_auth_roles(
identity_payload, strict_sync=strict_sync
)

return login
3 changes: 3 additions & 0 deletions auth_user_role_saml/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"
8 changes: 8 additions & 0 deletions auth_user_role_saml/readme/CONFIGURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
To configure SAML role synchronization:

1. Ensure your SAML Identity Provider is configured to send user attributes (e.g., `groups`, `roles`, or `department`) in its SAML assertions.
2. Configure your attribute mappings in **Settings > Users & Companies > Identity Role Mappings** (provided by the base `auth_user_role` module).
3. Navigate to **Settings > Users & Companies > SAML Providers** and open your provider.
4. Under the provider settings, you will find a **Strict Role Synchronization** checkbox:
* **Unchecked (Default):** Additive mode. Mapped roles are granted, but manually assigned roles in Odoo are left completely untouched.
* **Checked:** Strict mode. Odoo becomes a strict mirror of the IdP. Any roles the user possesses in Odoo that are *not* explicitly granted by the current SAML payload will be automatically removed upon login.
1 change: 1 addition & 0 deletions auth_user_role_saml/readme/CONTRIBUTORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* Andrea Stirpe
4 changes: 4 additions & 0 deletions auth_user_role_saml/readme/CREDITS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
The development of this module has been financially supported by:

* 360 ERP

4 changes: 4 additions & 0 deletions auth_user_role_saml/readme/DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
This is a glue module that bridges `auth_saml` and `auth_user_role`.

It intercepts the standard SAML sign-in process, extracts the identity payload (attributes) from the SAML response, and passes it to the generic role evaluation engine.
This allows administrators to automatically provision Odoo roles based on groups or attributes defined in Azure AD, Keycloak, Okta, or any other SAML 2.0 Identity Provider.
3 changes: 3 additions & 0 deletions auth_user_role_saml/readme/USAGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Once configured, users simply log in using the SAML Identity Provider button on the Odoo login screen.

Upon successful authentication, the module will parse the SAML identity payload, evaluate it against the active mapping rules, and apply the roles before the user's Odoo session is fully initialized.
Binary file added auth_user_role_saml/static/description/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading