diff --git a/openslides/global_settings.py b/openslides/global_settings.py index 7da0ea348..7e56a7886 100644 --- a/openslides/global_settings.py +++ b/openslides/global_settings.py @@ -7,10 +7,6 @@ from openslides.utils.plugins import collect_plugins SITE_ROOT = os.path.realpath(os.path.dirname(__file__)) -AUTHENTICATION_BACKENDS = ( - 'django.contrib.auth.backends.ModelBackend', - 'openslides.utils.auth.AnonymousAuth',) - AUTH_USER_MODEL = 'users.User' LOGIN_URL = '/login/' @@ -71,7 +67,7 @@ MIDDLEWARE_CLASSES = ( 'django.middleware.locale.LocaleMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'openslides.users.auth.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'openslides.config.middleware.ConfigCacheMiddleware', ) @@ -102,12 +98,11 @@ INSTALLED_APPS = ( ) TEMPLATE_CONTEXT_PROCESSORS = ( - 'django.contrib.auth.context_processors.auth', + 'openslides.users.auth.auth', 'django.contrib.messages.context_processors.messages', 'django.core.context_processors.request', 'django.core.context_processors.i18n', 'django.core.context_processors.static', - 'openslides.utils.auth.anonymous_context_additions', 'openslides.utils.main_menu.main_menu_entries', 'openslides.core.chatbox.chat_messages_context_processor', ) diff --git a/openslides/users/auth.py b/openslides/users/auth.py new file mode 100644 index 000000000..00b94c8dc --- /dev/null +++ b/openslides/users/auth.py @@ -0,0 +1,101 @@ +from django.contrib.auth.models import AnonymousUser as DjangoAnonymousUser, Permission +from django.contrib.auth.context_processors import auth as _auth +from django.contrib.auth import get_user as _get_user +from django.utils.functional import SimpleLazyObject + +from openslides.config.api import config + + +class AnonymousUser(DjangoAnonymousUser): + """ + Class for anonymous user instances, which have the permissions from the + Group 'Anonymous' (pk=1). + """ + + def get_all_permissions(self, obj=None): + """ + Return the permissions a user is granted by his group membership(s). + + Try to return the permissions for the 'Anonymous' group (pk=1). + """ + perms = Permission.objects.filter(group__pk=1) + if perms is None: + return set() + # TODO: test without order_by() + perms = perms.values_list('content_type__app_label', 'codename').order_by() + return set(['%s.%s' % (content_type, codename) for content_type, codename in perms]) + + def has_perm(self, perm, obj=None): + """ + Check if the user has a specific permission + """ + return (perm in self.get_all_permissions()) + + def has_module_perms(self, app_label): + """ + Check if the user has permissions on the module app_label + """ + for perm in self.get_all_permissions(): + if perm[:perm.index('.')] == app_label: + return True + return False + + +class AuthenticationMiddleware(object): + """ + Middleware to get the logged in user in users. + + Uses AnonymousUser instead of the django anonymous user. + """ + def process_request(self, request): + """ + Like django.contrib.auth.middleware.AuthenticationMiddleware, but uses + our own get_user function. + """ + assert hasattr(request, 'session'), ( + "The authentication middleware requires session middleware " + "to be installed. Edit your MIDDLEWARE_CLASSES setting to insert " + "'django.contrib.sessions.middleware.SessionMiddleware' before " + "'openslides.users.auth.AuthenticationMiddleware'." + ) + request.user = SimpleLazyObject(lambda: get_user(request)) + + +def get_user(request): + """ + Gets the user from the request. + + This is a mix of django.contrib.auth.get_user and + django.contrib.auth.middleware.get_user which uses our anonymous user. + """ + try: + return_user = request._cached_user + except AttributeError: + # Get the user. If it is a DjangoAnonymousUser, then use our AnonymousUser + return_user = _get_user(request) + if config['system_enable_anonymous'] and isinstance(return_user, DjangoAnonymousUser): + return_user = AnonymousUser() + request._cached_user = return_user + return return_user + + +def auth(request): + """ + Contextmanager to handle auth. + + Uses the django auth context manager to fill the context. + + Alters the attribute user if the user is not authenticated. + """ + # Call the django standard auth function, like 'super()' + context = _auth(request) + + # Change the django anonymous user with our anonymous user if anonymous auth + # is enabled + if config['system_enable_anonymous'] and isinstance(context['user'], DjangoAnonymousUser): + context['user'] = AnonymousUser() + + # Set a context variable that will indicate if anonymous login is possible + context['os_enable_anonymous_login'] = config['system_enable_anonymous'] + + return context diff --git a/openslides/utils/auth/AnonymousAuth.py b/openslides/utils/auth/AnonymousAuth.py deleted file mode 100644 index daa93b547..000000000 --- a/openslides/utils/auth/AnonymousAuth.py +++ /dev/null @@ -1,85 +0,0 @@ -from django.contrib.auth.models import Permission - -from openslides.config.api import config - - -class AnonymousAuth(object): - """ - Authenticates the AnonymousUser against the Permission-Group 'Anonymous'. - No rights are granted unless the group is defined and contains them. - """ - supports_anonymous_user = True - supports_inactive_user = True - supports_object_permissions = False - - def authenticate(self, username=None, password=None): - """ - Authenticate a user based in username / password. - - - always return None as anonymous can't login. - """ - return None - - def get_group_permissions(self, user_obj, obj=None): - """ - Return the permissions a user is granted by his group membership(s). - - - try to return the permissions for the 'Anonymous' group (pk=1). - """ - if (not user_obj.is_anonymous() or obj is not None or - not config['system_enable_anonymous']): - return set() - - perms = Permission.objects.filter(group__pk=1) - if perms is None: - return set() - perms = perms.values_list('content_type__app_label', 'codename') \ - .order_by() - return set([u'%s.%s' % (ct, name) for ct, name in perms]) - - def get_all_permissions(self, user_obj, obj=None): - """ - Return all permissions a user is granted including group permissions. - - - for anonymous it's identical to get_group_permissions - """ - return self.get_group_permissions(user_obj, obj) - - def has_perm(self, user_obj, perm, obj=None): - """ - Check if the user as a specific permission - """ - if (not user_obj.is_anonymous() or obj is not None or - not config['system_enable_anonymous']): - return False - - return (perm in self.get_all_permissions(user_obj)) - - def has_module_perm(self, user_obj, app_label): - """ - Check if the user has permissions on the module app_label - """ - if (not user_obj.is_anonymous() or - not config['system_enable_anonymous']): - return False - - for perm in self.get_all_permissions(user_obj): - if perm[:perm.index('.')] == app_label: - return True - return False - - def get_user(self, user_id): - """ - Return the User object for user_id - - - for anonymous it's always None - """ - return None - - -def anonymous_context_additions(RequestContext): - """ - Add a variable to the request context that will indicate - if anonymous login is possible at all. - """ - return {'os_enable_anonymous_login': config['system_enable_anonymous']} diff --git a/openslides/utils/auth/__init__.py b/openslides/utils/auth/__init__.py deleted file mode 100644 index 5a568e305..000000000 --- a/openslides/utils/auth/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .AnonymousAuth import * # noqa