mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-08-19 12:36:06 +00:00
groups: User permissions for access to apps based on LDAP groups
- More user-friendly treatment of groups and their permissions Closes #690 Signed-off-by: Joseph Nuthalapati <njoseph@thoughtworks.com> Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
parent
2f67fb49d4
commit
7ce5d1f636
@ -346,17 +346,6 @@ def subcommand_remove_user_from_group(arguments):
|
||||
flush_cache()
|
||||
|
||||
|
||||
def subcommand_get_all_groups(_):
|
||||
"""Get all user groups"""
|
||||
get_groups = "getent group".split()
|
||||
cut_names = "cut -d: -f1".split()
|
||||
groups = subprocess.Popen(get_groups, stdout=subprocess.PIPE, shell=False)
|
||||
trimmed_groups = subprocess.Popen(cut_names, stdin=groups.stdout,
|
||||
stdout=subprocess.PIPE, shell=False)
|
||||
groups.stdout.close()
|
||||
print(trimmed_groups.communicate()[0].decode())
|
||||
|
||||
|
||||
def flush_cache():
|
||||
"""Flush nscd cache."""
|
||||
_run(['nscd', '--invalidate=passwd'])
|
||||
|
||||
@ -8,12 +8,12 @@ Alias /tt-rss-app /usr/share/tt-rss/www
|
||||
<Location /tt-rss>
|
||||
Include includes/freedombox-single-sign-on.conf
|
||||
<IfModule mod_auth_pubtkt.c>
|
||||
TKTAuthToken "newsfeed" "admin"
|
||||
TKTAuthToken "feed-reader" "admin"
|
||||
</IfModule>
|
||||
</Location>
|
||||
|
||||
<Location /tt-rss-app>
|
||||
Include includes/freedombox-auth-ldap.conf
|
||||
Require valid-user
|
||||
# TODO Restrict access to `newsfeed` group
|
||||
# TODO Restrict access to `feed-reader` group
|
||||
</Location>
|
||||
|
||||
@ -26,7 +26,7 @@ from plinth import action_utils
|
||||
from plinth import frontpage
|
||||
from plinth import service as service_module
|
||||
from plinth.menu import main_menu
|
||||
from plinth.modules.users import add_group
|
||||
from plinth.modules.users import create_group, register_group
|
||||
from .manifest import clients
|
||||
|
||||
|
||||
@ -51,6 +51,8 @@ description = [
|
||||
'it immediately after enabling this service.')
|
||||
]
|
||||
|
||||
group = ('bit-torrent', _('Download files using BitTorrent applications'))
|
||||
|
||||
reserved_usernames = ['debian-deluged']
|
||||
|
||||
clients = clients
|
||||
@ -72,6 +74,7 @@ def init():
|
||||
|
||||
if is_enabled():
|
||||
add_shortcut()
|
||||
register_group(group)
|
||||
|
||||
|
||||
def setup(helper, old_version=None):
|
||||
@ -86,7 +89,7 @@ def setup(helper, old_version=None):
|
||||
disable=disable)
|
||||
helper.call('post', service.notify_enabled, None, True)
|
||||
helper.call('post', add_shortcut)
|
||||
add_group('bittorrent')
|
||||
create_group(group[0])
|
||||
|
||||
|
||||
def add_shortcut():
|
||||
|
||||
@ -28,6 +28,7 @@ from plinth import cfg
|
||||
from plinth import frontpage
|
||||
from plinth import service as service_module
|
||||
from plinth.menu import main_menu
|
||||
from plinth.modules.users import create_group, register_group
|
||||
from .manifest import clients
|
||||
|
||||
|
||||
@ -61,6 +62,9 @@ description = [
|
||||
clients = clients
|
||||
|
||||
|
||||
group = ('wiki', _('View and edit wiki applications'))
|
||||
|
||||
|
||||
def init():
|
||||
"""Initialize the ikiwiki module."""
|
||||
menu = main_menu.get('apps')
|
||||
@ -75,6 +79,7 @@ def init():
|
||||
|
||||
if is_enabled():
|
||||
add_shortcuts()
|
||||
register_group(group)
|
||||
|
||||
|
||||
def setup(helper, old_version=None):
|
||||
@ -88,6 +93,7 @@ def setup(helper, old_version=None):
|
||||
is_enabled=is_enabled, enable=enable, disable=disable)
|
||||
helper.call('post', service.notify_enabled, None, True)
|
||||
helper.call('post', add_shortcuts)
|
||||
create_group(group[0])
|
||||
|
||||
|
||||
def add_shortcuts():
|
||||
|
||||
@ -25,7 +25,7 @@ from django.utils.translation import ugettext_lazy as _
|
||||
from plinth import service as service_module
|
||||
from plinth import action_utils, actions, frontpage
|
||||
from plinth.menu import main_menu
|
||||
from plinth.modules.users import add_group
|
||||
from plinth.modules.users import create_group, register_group
|
||||
|
||||
from .manifest import clients
|
||||
|
||||
@ -37,7 +37,7 @@ managed_packages = ['transmission-daemon']
|
||||
|
||||
name = _('Transmission')
|
||||
|
||||
short_description = _('BitTorrent')
|
||||
short_description = _('BitTorrent Web Client')
|
||||
|
||||
description = [
|
||||
_('BitTorrent is a peer-to-peer file sharing protocol. '
|
||||
@ -50,6 +50,8 @@ clients = clients
|
||||
|
||||
reserved_usernames = ['debian-transmission']
|
||||
|
||||
group = ('bit-torrent', _('Download files using BitTorrent applications'))
|
||||
|
||||
service = None
|
||||
|
||||
|
||||
@ -69,6 +71,7 @@ def init():
|
||||
|
||||
if is_enabled():
|
||||
add_shortcut()
|
||||
register_group(group)
|
||||
|
||||
|
||||
def setup(helper, old_version=None):
|
||||
@ -92,7 +95,7 @@ def setup(helper, old_version=None):
|
||||
disable=disable)
|
||||
helper.call('post', service.notify_enabled, None, True)
|
||||
helper.call('post', add_shortcut)
|
||||
add_group('bit-torrent')
|
||||
create_group(group[0])
|
||||
|
||||
|
||||
def add_shortcut():
|
||||
|
||||
@ -28,7 +28,7 @@ from plinth import cfg
|
||||
from plinth import frontpage
|
||||
from plinth import service as service_module
|
||||
from plinth.menu import main_menu
|
||||
from plinth.modules.users import add_group
|
||||
from plinth.modules.users import create_group, register_group
|
||||
from .manifest import clients
|
||||
|
||||
|
||||
@ -61,6 +61,8 @@ description = [
|
||||
|
||||
clients = clients
|
||||
|
||||
group = ('feed-reader', _('Read and subscribe to news feeds'))
|
||||
|
||||
service = None
|
||||
|
||||
|
||||
@ -80,6 +82,7 @@ def init():
|
||||
|
||||
if is_enabled():
|
||||
add_shortcut()
|
||||
register_group(group)
|
||||
|
||||
|
||||
def setup(helper, old_version=None):
|
||||
@ -95,7 +98,7 @@ def setup(helper, old_version=None):
|
||||
is_enabled=is_enabled, enable=enable, disable=disable)
|
||||
helper.call('post', service.notify_enabled, None, True)
|
||||
helper.call('post', add_shortcut)
|
||||
add_group('newsfeed')
|
||||
create_group(group[0])
|
||||
|
||||
|
||||
def add_shortcut():
|
||||
|
||||
@ -45,6 +45,9 @@ first_boot_steps = [
|
||||
|
||||
name = _('Users and Groups')
|
||||
|
||||
# List of all Plinth user groups
|
||||
groups = set()
|
||||
|
||||
|
||||
def init():
|
||||
"""Intialize the user module."""
|
||||
@ -87,7 +90,7 @@ def _diagnose_ldap_entry(search_item):
|
||||
.format(search_item=search_item), result]
|
||||
|
||||
|
||||
def add_group(group):
|
||||
def create_group(group):
|
||||
"""Add an LDAP group."""
|
||||
actions.superuser_run('users', options=['create-group', group])
|
||||
|
||||
@ -104,3 +107,7 @@ def get_all_groups():
|
||||
return set(groups.strip().split())
|
||||
except ActionError:
|
||||
return {}
|
||||
|
||||
|
||||
def register_group(group):
|
||||
groups.add(group)
|
||||
|
||||
@ -28,23 +28,18 @@ from django.utils.translation import ugettext as _, ugettext_lazy
|
||||
from plinth import actions
|
||||
from plinth.errors import ActionError
|
||||
from plinth.modules import first_boot
|
||||
from plinth.modules import users
|
||||
from plinth.modules.security import set_restricted_access
|
||||
from plinth.modules.users import get_all_groups
|
||||
from plinth.utils import is_user_admin
|
||||
from plinth import module_loader
|
||||
|
||||
PLINTH_APP_GROUPS = {
|
||||
'admin',
|
||||
'newsfeed',
|
||||
}
|
||||
|
||||
|
||||
def get_group_choices():
|
||||
groups = PLINTH_APP_GROUPS.intersection(get_all_groups())
|
||||
return ((group, _(group)) for group in groups)
|
||||
|
||||
|
||||
GROUP_CHOICES = get_group_choices()
|
||||
"""Return localized group description and group name in one string."""
|
||||
admin_group = ('admin', _('Access to all services and system settings'))
|
||||
users.register_group(admin_group)
|
||||
choices = {(g[0], ('{} ({})'.format(g[1], g[0]))) for g in users.groups}
|
||||
return sorted(list(choices), key=lambda g: g[0])
|
||||
|
||||
|
||||
class ValidNewUsernameCheckMixin(object):
|
||||
@ -84,10 +79,9 @@ class CreateUserForm(ValidNewUsernameCheckMixin, UserCreationForm):
|
||||
|
||||
Include options to add user to groups.
|
||||
"""
|
||||
|
||||
groups = forms.MultipleChoiceField(
|
||||
choices=GROUP_CHOICES,
|
||||
label=ugettext_lazy('Groups'),
|
||||
choices=get_group_choices(),
|
||||
label=ugettext_lazy('Permissions'),
|
||||
required=False,
|
||||
widget=forms.CheckboxSelectMultiple,
|
||||
help_text=ugettext_lazy(
|
||||
@ -103,6 +97,7 @@ class CreateUserForm(ValidNewUsernameCheckMixin, UserCreationForm):
|
||||
"""Initialize the form with extra request argument."""
|
||||
self.request = request
|
||||
super(CreateUserForm, self).__init__(*args, **kwargs)
|
||||
self.fields['groups'].choices = get_group_choices()
|
||||
|
||||
def save(self, commit=True):
|
||||
"""Save the user model and create LDAP user if required."""
|
||||
@ -158,14 +153,21 @@ class UserUpdateForm(ValidNewUsernameCheckMixin, forms.ModelForm):
|
||||
|
||||
def __init__(self, request, username, *args, **kwargs):
|
||||
"""Initialize the form with extra request argument."""
|
||||
for group, group_name in GROUP_CHOICES:
|
||||
group_choices = dict(get_group_choices())
|
||||
for group in group_choices:
|
||||
Group.objects.get_or_create(name=group)
|
||||
|
||||
self.request = request
|
||||
self.username = username
|
||||
|
||||
super(UserUpdateForm, self).__init__(*args, **kwargs)
|
||||
|
||||
choices = [ # Replace group names with descriptions
|
||||
(c[0], group_choices[c[1]])
|
||||
for c in sorted(self.fields['groups'].choices, key=lambda x: x[1])]
|
||||
|
||||
self.fields['groups'].label = 'Permissions'
|
||||
self.fields['groups'].choices = choices
|
||||
|
||||
if not is_user_admin(request):
|
||||
self.fields['is_active'].widget = forms.HiddenInput()
|
||||
self.fields['groups'].disabled = True
|
||||
@ -278,7 +280,7 @@ class FirstBootForm(ValidNewUsernameCheckMixin, auth.forms.UserCreationForm):
|
||||
_('Failed to add new user to admin group.'))
|
||||
|
||||
# Create initial Django groups
|
||||
for group_choice in GROUP_CHOICES:
|
||||
for group_choice in get_group_choices():
|
||||
auth.models.Group.objects.get_or_create(name=group_choice[0])
|
||||
|
||||
admin_group = auth.models.Group.objects.get(name='admin')
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user