You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

__init__.py 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. """
  2. Creates permissions for all installed apps that need permissions.
  3. """
  4. import getpass
  5. import unicodedata
  6. from django.apps import apps as global_apps
  7. from django.contrib.auth import get_permission_codename
  8. from django.contrib.contenttypes.management import create_contenttypes
  9. from django.core import exceptions
  10. from django.db import DEFAULT_DB_ALIAS, router
  11. def _get_all_permissions(opts):
  12. """
  13. Return (codename, name) for all permissions in the given opts.
  14. """
  15. return [*_get_builtin_permissions(opts), *opts.permissions]
  16. def _get_builtin_permissions(opts):
  17. """
  18. Return (codename, name) for all autogenerated permissions.
  19. By default, this is ('add', 'change', 'delete', 'view')
  20. """
  21. perms = []
  22. for action in opts.default_permissions:
  23. perms.append((
  24. get_permission_codename(action, opts),
  25. 'Can %s %s' % (action, opts.verbose_name_raw)
  26. ))
  27. return perms
  28. def create_permissions(app_config, verbosity=2, interactive=True, using=DEFAULT_DB_ALIAS, apps=global_apps, **kwargs):
  29. if not app_config.models_module:
  30. return
  31. # Ensure that contenttypes are created for this app. Needed if
  32. # 'django.contrib.auth' is in INSTALLED_APPS before
  33. # 'django.contrib.contenttypes'.
  34. create_contenttypes(app_config, verbosity=verbosity, interactive=interactive, using=using, apps=apps, **kwargs)
  35. app_label = app_config.label
  36. try:
  37. app_config = apps.get_app_config(app_label)
  38. ContentType = apps.get_model('contenttypes', 'ContentType')
  39. Permission = apps.get_model('auth', 'Permission')
  40. except LookupError:
  41. return
  42. if not router.allow_migrate_model(using, Permission):
  43. return
  44. # This will hold the permissions we're looking for as
  45. # (content_type, (codename, name))
  46. searched_perms = []
  47. # The codenames and ctypes that should exist.
  48. ctypes = set()
  49. for klass in app_config.get_models():
  50. # Force looking up the content types in the current database
  51. # before creating foreign keys to them.
  52. ctype = ContentType.objects.db_manager(using).get_for_model(klass, for_concrete_model=False)
  53. ctypes.add(ctype)
  54. for perm in _get_all_permissions(klass._meta):
  55. searched_perms.append((ctype, perm))
  56. # Find all the Permissions that have a content_type for a model we're
  57. # looking for. We don't need to check for codenames since we already have
  58. # a list of the ones we're going to create.
  59. all_perms = set(Permission.objects.using(using).filter(
  60. content_type__in=ctypes,
  61. ).values_list(
  62. "content_type", "codename"
  63. ))
  64. perms = [
  65. Permission(codename=codename, name=name, content_type=ct)
  66. for ct, (codename, name) in searched_perms
  67. if (ct.pk, codename) not in all_perms
  68. ]
  69. Permission.objects.using(using).bulk_create(perms)
  70. if verbosity >= 2:
  71. for perm in perms:
  72. print("Adding permission '%s'" % perm)
  73. def get_system_username():
  74. """
  75. Return the current system user's username, or an empty string if the
  76. username could not be determined.
  77. """
  78. try:
  79. result = getpass.getuser()
  80. except (ImportError, KeyError):
  81. # KeyError will be raised by os.getpwuid() (called by getuser())
  82. # if there is no corresponding entry in the /etc/passwd file
  83. # (a very restricted chroot environment, for example).
  84. return ''
  85. return result
  86. def get_default_username(check_db=True):
  87. """
  88. Try to determine the current system user's username to use as a default.
  89. :param check_db: If ``True``, requires that the username does not match an
  90. existing ``auth.User`` (otherwise returns an empty string).
  91. :returns: The username, or an empty string if no username can be
  92. determined.
  93. """
  94. # This file is used in apps.py, it should not trigger models import.
  95. from django.contrib.auth import models as auth_app
  96. # If the User model has been swapped out, we can't make any assumptions
  97. # about the default user name.
  98. if auth_app.User._meta.swapped:
  99. return ''
  100. default_username = get_system_username()
  101. try:
  102. default_username = (
  103. unicodedata.normalize('NFKD', default_username)
  104. .encode('ascii', 'ignore').decode('ascii')
  105. .replace(' ', '').lower()
  106. )
  107. except UnicodeDecodeError:
  108. return ''
  109. # Run the username validator
  110. try:
  111. auth_app.User._meta.get_field('username').run_validators(default_username)
  112. except exceptions.ValidationError:
  113. return ''
  114. # Don't return the default username if it is already taken.
  115. if check_db and default_username:
  116. try:
  117. auth_app.User._default_manager.get(username=default_username)
  118. except auth_app.User.DoesNotExist:
  119. pass
  120. else:
  121. return ''
  122. return default_username