123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- """
- Creates permissions for all installed apps that need permissions.
- """
- import getpass
- import unicodedata
-
- from django.apps import apps as global_apps
- from django.contrib.auth import get_permission_codename
- from django.contrib.contenttypes.management import create_contenttypes
- from django.core import exceptions
- from django.db import DEFAULT_DB_ALIAS, router
-
-
- def _get_all_permissions(opts):
- """
- Return (codename, name) for all permissions in the given opts.
- """
- return [*_get_builtin_permissions(opts), *opts.permissions]
-
-
- def _get_builtin_permissions(opts):
- """
- Return (codename, name) for all autogenerated permissions.
- By default, this is ('add', 'change', 'delete', 'view')
- """
- perms = []
- for action in opts.default_permissions:
- perms.append((
- get_permission_codename(action, opts),
- 'Can %s %s' % (action, opts.verbose_name_raw)
- ))
- return perms
-
-
- def create_permissions(app_config, verbosity=2, interactive=True, using=DEFAULT_DB_ALIAS, apps=global_apps, **kwargs):
- if not app_config.models_module:
- return
-
- # Ensure that contenttypes are created for this app. Needed if
- # 'django.contrib.auth' is in INSTALLED_APPS before
- # 'django.contrib.contenttypes'.
- create_contenttypes(app_config, verbosity=verbosity, interactive=interactive, using=using, apps=apps, **kwargs)
-
- app_label = app_config.label
- try:
- app_config = apps.get_app_config(app_label)
- ContentType = apps.get_model('contenttypes', 'ContentType')
- Permission = apps.get_model('auth', 'Permission')
- except LookupError:
- return
-
- if not router.allow_migrate_model(using, Permission):
- return
-
- # This will hold the permissions we're looking for as
- # (content_type, (codename, name))
- searched_perms = []
- # The codenames and ctypes that should exist.
- ctypes = set()
- for klass in app_config.get_models():
- # Force looking up the content types in the current database
- # before creating foreign keys to them.
- ctype = ContentType.objects.db_manager(using).get_for_model(klass, for_concrete_model=False)
-
- ctypes.add(ctype)
- for perm in _get_all_permissions(klass._meta):
- searched_perms.append((ctype, perm))
-
- # Find all the Permissions that have a content_type for a model we're
- # looking for. We don't need to check for codenames since we already have
- # a list of the ones we're going to create.
- all_perms = set(Permission.objects.using(using).filter(
- content_type__in=ctypes,
- ).values_list(
- "content_type", "codename"
- ))
-
- perms = [
- Permission(codename=codename, name=name, content_type=ct)
- for ct, (codename, name) in searched_perms
- if (ct.pk, codename) not in all_perms
- ]
- Permission.objects.using(using).bulk_create(perms)
- if verbosity >= 2:
- for perm in perms:
- print("Adding permission '%s'" % perm)
-
-
- def get_system_username():
- """
- Return the current system user's username, or an empty string if the
- username could not be determined.
- """
- try:
- result = getpass.getuser()
- except (ImportError, KeyError):
- # KeyError will be raised by os.getpwuid() (called by getuser())
- # if there is no corresponding entry in the /etc/passwd file
- # (a very restricted chroot environment, for example).
- return ''
- return result
-
-
- def get_default_username(check_db=True):
- """
- Try to determine the current system user's username to use as a default.
-
- :param check_db: If ``True``, requires that the username does not match an
- existing ``auth.User`` (otherwise returns an empty string).
- :returns: The username, or an empty string if no username can be
- determined.
- """
- # This file is used in apps.py, it should not trigger models import.
- from django.contrib.auth import models as auth_app
-
- # If the User model has been swapped out, we can't make any assumptions
- # about the default user name.
- if auth_app.User._meta.swapped:
- return ''
-
- default_username = get_system_username()
- try:
- default_username = (
- unicodedata.normalize('NFKD', default_username)
- .encode('ascii', 'ignore').decode('ascii')
- .replace(' ', '').lower()
- )
- except UnicodeDecodeError:
- return ''
-
- # Run the username validator
- try:
- auth_app.User._meta.get_field('username').run_validators(default_username)
- except exceptions.ValidationError:
- return ''
-
- # Don't return the default username if it is already taken.
- if check_db and default_username:
- try:
- auth_app.User._default_manager.get(username=default_username)
- except auth_app.User.DoesNotExist:
- pass
- else:
- return ''
- return default_username
|