diff --git a/README.md b/README.md
index ab14d1d..f16438c 100644
--- a/README.md
+++ b/README.md
@@ -48,4 +48,5 @@ Im Ansible-Repo müssen diese Sachen hinzugefügt werden:
## License
-This CCCHH ansible-ccchh repository is licensed under the [MIT License](./LICENSE).
+This CCCHH ansible-ccchh repository is licensed under the [MIT License](./LICENSE).
+[`0001_oidc_group_and_role_mapping_custom_pipeline.patch`](./roles/netbox/files/0001_oidc_group_and_role_mapping_custom_pipeline.patch) is licensed under the Creative Commons: CC BY-SA 4.0 license.
diff --git a/roles/netbox/README.md b/roles/netbox/README.md
index 38b7968..a83cffe 100644
--- a/roles/netbox/README.md
+++ b/roles/netbox/README.md
@@ -18,7 +18,9 @@ Should work on Debian-based distributions.
## Optional Arguments
-None.
+- `netbox__patch_oidc_group_and_role_mapping_custom_pipeline`: Whether or not to patch NetBox to add custom pipeline code for OIDC group and role mapping.
+ See [Custom Pipeline Code for OIDC Group and Role Mapping](#custom-pipeline-code-for-oidc-group-and-role-mapping) for more infos.
+ Defaults to `false`.
## NetBox Configuration
@@ -71,6 +73,14 @@ The relevant documentation on how to do that can be found here:
- Web server setup docs:
- Example base nginx config:
+## Custom Pipeline Code for OIDC Group and Role Mapping
+
+Setting the option `netbox__patch_oidc_group_and_role_mapping_custom_pipeline` to `true` makes this role patch NetBox to add custom pipeline code for OIDC group and role mapping.
+Note that this role uses a patch for NetBox >= 4.0.0.
+The patch is available in `files/0001_oidc_group_and_role_mapping_custom_pipeline.patch`, licensed under the CC BY-SA 4.0 license and taken from [this authentik NetBox documentation](https://docs.goauthentik.io/integrations/services/netbox/).
+The documentation also shows how to use the pipeline code by defining a custom `SOCIAL_AUTH_PIPELINE`, which you also need to do, as the configuration isn't provided by this role.
+See also [the default settings.py](https://github.com/netbox-community/netbox/blob/main/netbox/netbox/settings.py) for the default `SOCIAL_AUTH_PIPELINE`.
+
## Links & Resources
- The NetBox Git Repo:
diff --git a/roles/netbox/defaults/main.yaml b/roles/netbox/defaults/main.yaml
new file mode 100644
index 0000000..5dcbbee
--- /dev/null
+++ b/roles/netbox/defaults/main.yaml
@@ -0,0 +1 @@
+netbox__patch_oidc_group_and_role_mapping_custom_pipeline: false
diff --git a/roles/netbox/files/0001_oidc_group_and_role_mapping_custom_pipeline.patch b/roles/netbox/files/0001_oidc_group_and_role_mapping_custom_pipeline.patch
new file mode 100644
index 0000000..89f805a
--- /dev/null
+++ b/roles/netbox/files/0001_oidc_group_and_role_mapping_custom_pipeline.patch
@@ -0,0 +1,61 @@
+diff --git a/netbox/netbox/custom_pipeline.py b/netbox/netbox/custom_pipeline.py
+new file mode 100644
+index 000000000..470f388dc
+--- /dev/null
++++ b/netbox/netbox/custom_pipeline.py
+@@ -0,0 +1,55 @@
++# Licensed under Creative Commons: CC BY-SA 4.0 license.
++# https://github.com/goauthentik/authentik/blob/main/LICENSE
++# https://github.com/goauthentik/authentik/blob/main/website/integrations/services/netbox/index.md
++# https://docs.goauthentik.io/integrations/services/netbox/
++from netbox.authentication import Group
++
++class AuthFailed(Exception):
++ pass
++
++def add_groups(response, user, backend, *args, **kwargs):
++ try:
++ groups = response['groups']
++ except KeyError:
++ pass
++
++ # Add all groups from oAuth token
++ for group in groups:
++ group, created = Group.objects.get_or_create(name=group)
++ user.groups.add(group)
++
++def remove_groups(response, user, backend, *args, **kwargs):
++ try:
++ groups = response['groups']
++ except KeyError:
++ # Remove all groups if no groups in oAuth token
++ user.groups.clear()
++ pass
++
++ # Get all groups of user
++ user_groups = [item.name for item in user.groups.all()]
++ # Get groups of user which are not part of oAuth token
++ delete_groups = list(set(user_groups) - set(groups))
++
++ # Delete non oAuth token groups
++ for delete_group in delete_groups:
++ group = Group.objects.get(name=delete_group)
++ user.groups.remove(group)
++
++
++def set_roles(response, user, backend, *args, **kwargs):
++ # Remove Roles temporary
++ user.is_superuser = False
++ user.is_staff = False
++ try:
++ groups = response['groups']
++ except KeyError:
++ # When no groups are set
++ # save the user without Roles
++ user.save()
++ pass
++
++ # Set roles is role (superuser or staff) is in groups
++ user.is_superuser = True if 'superusers' in groups else False
++ user.is_staff = True if 'staff' in groups else False
++ user.save()
diff --git a/roles/netbox/meta/argument_specs.yaml b/roles/netbox/meta/argument_specs.yaml
index f836b43..c0368ef 100644
--- a/roles/netbox/meta/argument_specs.yaml
+++ b/roles/netbox/meta/argument_specs.yaml
@@ -10,3 +10,7 @@ argument_specs:
netbox__config:
type: str
required: true
+ netbox__patch_oidc_group_and_role_mapping_custom_pipeline:
+ type: bool
+ required: false
+ default: false
diff --git a/roles/netbox/tasks/main.yaml b/roles/netbox/tasks/main.yaml
index 89bf4a6..0d2cdce 100644
--- a/roles/netbox/tasks/main.yaml
+++ b/roles/netbox/tasks/main.yaml
@@ -25,6 +25,14 @@
- Run upgrade script
- Ensure netbox systemd services are set up and up-to-date
+- name: Ensure patch for adding custom pipeline code for OIDC group and role mapping is applied
+ ansible.posix.patch:
+ src: 0001_oidc_group_and_role_mapping_custom_pipeline.patch
+ basedir: /opt/netbox/
+ when: netbox__patch_oidc_group_and_role_mapping_custom_pipeline
+ notify:
+ - Ensure netbox systemd services are set up and up-to-date
+
- name: Ensure netbox user
block:
- name: Ensure netbox group exists