Skip to content

Commit

Permalink
Fixes netbox-community#7671: Add REMOTE_AUTH_AUTO_CREATE_GROUPS
Browse files Browse the repository at this point in the history
When REMOTE_AUTH_AUTO_CREATE_GROUPS is True, Netbox will create groups
referenced in the REMOTE_AUTH_GROUP_HEADER that don't exist in the
database.
  • Loading branch information
larsks committed Oct 28, 2021
1 parent a090955 commit 5f1e304
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 4 deletions.
9 changes: 9 additions & 0 deletions docs/configuration/optional-settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,15 @@ Default width (in pixels) of a unit within a rack elevation.

---

## REMOTE_AUTH_AUTO_CREATE_GROUPS

Default: `False`

If `True`, NetBox will automatically create local groups to mirror
remote user groups (requires `REMOTE_AUTH_GROUP_SYNC_ENABLED`).

---

## REMOTE_AUTH_AUTO_CREATE_USER

Default: `False`
Expand Down
23 changes: 19 additions & 4 deletions netbox/netbox/authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,17 +104,32 @@ class RemoteUserBackend(_RemoteUserBackend):
def create_unknown_user(self):
return settings.REMOTE_AUTH_AUTO_CREATE_USER

@property
def create_unknown_groups(self):
return settings.REMOTE_AUTH_AUTO_CREATE_GROUPS

def configure_groups(self, user, remote_groups):
logger = logging.getLogger('netbox.authentication.RemoteUserBackend')

# Assign default groups to the user
# Assign remote groups to the user
group_list = []
for name in remote_groups:
try:
group_list.append(Group.objects.get(name=name))
if self.create_unknown_groups:
group, created = Group._default_manager.get_or_create(name=name)
if created:
logger.debug(f"Created group {name}")
else:
group = Group.objects.get(name=name)

group_list.append(group)
except Group.DoesNotExist:
logging.error(
f"Could not assign group {name} to remotely-authenticated user {user}: Group not found")
if settings.REMOTE_AUTH_AUTO_CREATE_GROUPS:
group_list.append(Group.objects.create(name=name))
else:
logging.error(
f"Could not assign group {name} to remotely-authenticated user {user}: Group not found")

if group_list:
user.groups.set(group_list)
logger.debug(
Expand Down
1 change: 1 addition & 0 deletions netbox/netbox/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@
RACK_ELEVATION_DEFAULT_UNIT_HEIGHT = getattr(configuration, 'RACK_ELEVATION_DEFAULT_UNIT_HEIGHT', 22)
RACK_ELEVATION_DEFAULT_UNIT_WIDTH = getattr(configuration, 'RACK_ELEVATION_DEFAULT_UNIT_WIDTH', 220)
REMOTE_AUTH_AUTO_CREATE_USER = getattr(configuration, 'REMOTE_AUTH_AUTO_CREATE_USER', False)
REMOTE_AUTH_AUTO_CREATE_GROUPS = getattr(configuration, 'REMOTE_AUTH_AUTO_CREATE_GROUPS', False)
REMOTE_AUTH_BACKEND = getattr(configuration, 'REMOTE_AUTH_BACKEND', 'netbox.authentication.RemoteUserBackend')
REMOTE_AUTH_DEFAULT_GROUPS = getattr(configuration, 'REMOTE_AUTH_DEFAULT_GROUPS', [])
REMOTE_AUTH_DEFAULT_PERMISSIONS = getattr(configuration, 'REMOTE_AUTH_DEFAULT_PERMISSIONS', {})
Expand Down
44 changes: 44 additions & 0 deletions netbox/netbox/tests/test_authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,50 @@ def test_remote_auth_default_permissions(self):
self.assertTrue(new_user.has_perms(
['dcim.add_site', 'dcim.change_site']))

@override_settings(
REMOTE_AUTH_ENABLED=True,
REMOTE_AUTH_AUTO_CREATE_USER=True,
REMOTE_AUTH_AUTO_CREATE_GROUPS=True,
REMOTE_AUTH_GROUP_SYNC_ENABLED=True,
LOGIN_REQUIRED=True
)
def test_remote_auth_auto_create_groups(self):
"""
Test auto creating groups with group sync enabled.
"""

group_names = (
'Group 1',
'Group 2',
'Group 3',
)

headers = {
'HTTP_REMOTE_USER': 'remoteuser2',
'HTTP_REMOTE_USER_GROUP': '|'.join(group_names),
}

self.assertTrue(settings.REMOTE_AUTH_ENABLED)
self.assertTrue(settings.REMOTE_AUTH_AUTO_CREATE_USER)
self.assertTrue(settings.REMOTE_AUTH_AUTO_CREATE_GROUPS)
self.assertTrue(settings.REMOTE_AUTH_GROUP_SYNC_ENABLED)
self.assertEqual(settings.REMOTE_AUTH_HEADER, 'HTTP_REMOTE_USER')
self.assertEqual(settings.REMOTE_AUTH_GROUP_HEADER,
'HTTP_REMOTE_USER_GROUP')
self.assertEqual(settings.REMOTE_AUTH_GROUP_SEPARATOR, '|')

response = self.client.get(reverse('home'), follow=True, **headers)
self.assertEqual(response.status_code, 200)

new_user = User.objects.get(username='remoteuser2')
self.assertEqual(int(self.client.session.get(
'_auth_user_id')), new_user.pk, msg='Authentication failed')

self.assertListEqual(
group_names,
[g.name for g in new_user.groups.all()],
)

@override_settings(
REMOTE_AUTH_ENABLED=True,
REMOTE_AUTH_AUTO_CREATE_USER=True,
Expand Down

0 comments on commit 5f1e304

Please sign in to comment.