PageRenderTime 55ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/oauth/models.py

https://gitlab.com/darciga/api-auth
Python | 299 lines | 267 code | 14 blank | 18 comment | 17 complexity | 9f833cb459d2ff9c3f2ce5322e5a71bb MD5 | raw file
  1. __author__ = 'tingsystems'
  2. import uuid
  3. import string
  4. from django.contrib.auth.models import UserManager, PermissionsMixin, AbstractBaseUser, GroupManager, \
  5. PermissionManager
  6. from django.contrib.contenttypes.models import ContentType
  7. from django.contrib.auth.hashers import make_password
  8. from django.utils.encoding import python_2_unicode_compatible
  9. from django.core import validators
  10. from django.db import models
  11. from django.utils import six, timezone
  12. from django.utils.translation import ugettext_lazy as _
  13. from django.contrib import auth
  14. from rest_framework.exceptions import PermissionDenied, ValidationError
  15. from jsonfield import JSONField
  16. from auditlog.registry import auditlog
  17. def _simple_domain_name_validator(value):
  18. """
  19. Validates that the given value contains no whitespaces to prevent common
  20. typos.
  21. """
  22. if not value:
  23. return
  24. checks = ((s in value) for s in string.whitespace)
  25. if any(checks):
  26. raise ValidationError(_("The domain name cannot contain any spaces or tabs."))
  27. class Site(models.Model):
  28. id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
  29. logo = models.CharField(max_length=254, null=True, blank=True)
  30. name = models.CharField(max_length=128)
  31. slug = models.SlugField(unique=True)
  32. excerpt = models.CharField(max_length=200, null=True, blank=True)
  33. domain = models.CharField(
  34. max_length=100,
  35. validators=[_simple_domain_name_validator],
  36. unique=True,
  37. )
  38. email = models.EmailField()
  39. phone1 = models.CharField(max_length=20, null=True, blank=True)
  40. phone2 = models.CharField(max_length=20, null=True, blank=True)
  41. metadata = JSONField(null=True, blank=True)
  42. isActive = models.BooleanField(default=True)
  43. deployAt = models.DateField(null=True, blank=True)
  44. createdAt = models.DateTimeField(auto_now_add=True)
  45. updatedAt = models.DateTimeField(auto_now=True)
  46. def __str__(self):
  47. return self.name
  48. # A few helper functions for common logic between User and AnonymousUser.
  49. def _user_get_all_permissions(user, obj):
  50. permissions = set()
  51. for backend in auth.get_backends():
  52. if hasattr(backend, "get_all_permissions"):
  53. permissions.update(backend.get_all_permissions(user, obj))
  54. return permissions
  55. def _user_has_perm(user, perm, obj):
  56. """
  57. A backend can raise `PermissionDenied` to short-circuit permission checking.
  58. """
  59. for backend in auth.get_backends():
  60. if not hasattr(backend, 'has_perm'):
  61. continue
  62. try:
  63. if backend.has_perm(user, perm, obj):
  64. return True
  65. except PermissionDenied:
  66. return False
  67. return False
  68. def _user_has_module_perms(user, app_label):
  69. """
  70. A backend can raise `PermissionDenied` to short-circuit permission checking.
  71. """
  72. for backend in auth.get_backends():
  73. if not hasattr(backend, 'has_module_perms'):
  74. continue
  75. try:
  76. if backend.has_module_perms(user, app_label):
  77. return True
  78. except PermissionDenied:
  79. return False
  80. return False
  81. @python_2_unicode_compatible
  82. class Permission(models.Model):
  83. """
  84. The permissions system provides a way to assign permissions to specific
  85. users and groups of users.
  86. The permission system is used by the Django admin site, but may also be
  87. useful in your own code. The Django admin site uses permissions as follows:
  88. - The "add" permission limits the user's ability to view the "add" form
  89. and add an object.
  90. - The "change" permission limits a user's ability to view the change
  91. list, view the "change" form and change an object.
  92. - The "delete" permission limits the ability to delete an object.
  93. Permissions are set globally per type of object, not per specific object
  94. instance. It is possible to say "Mary may change news stories," but it's
  95. not currently possible to say "Mary may change news stories, but only the
  96. ones she created herself" or "Mary may only change news stories that have a
  97. certain status or publication date."
  98. Three basic permissions -- add, change and delete -- are automatically
  99. created for each Django model.
  100. """
  101. id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
  102. name = models.CharField(_('name'), max_length=255)
  103. content_type = models.ForeignKey(ContentType, related_name='ct_permission')
  104. codename = models.CharField(_('codename'), max_length=100)
  105. objects = PermissionManager()
  106. class Meta:
  107. verbose_name = _('permission')
  108. verbose_name_plural = _('permissions')
  109. unique_together = (('content_type', 'codename'),)
  110. ordering = ('content_type__app_label', 'content_type__model',
  111. 'codename')
  112. def __str__(self):
  113. return "%s | %s | %s" % (
  114. six.text_type(self.content_type.app_label),
  115. six.text_type(self.content_type),
  116. six.text_type(self.name))
  117. def natural_key(self):
  118. return (self.codename,) + self.content_type.natural_key()
  119. natural_key.dependencies = ['contenttypes.contenttype']
  120. @python_2_unicode_compatible
  121. class Group(models.Model):
  122. """
  123. Groups are a generic way of categorizing users to apply permissions, or
  124. some other label, to those users. A user can belong to any number of
  125. groups.
  126. A user in a group automatically has all the permissions granted to that
  127. group. For example, if the group Site editors has the permission
  128. can_edit_home_page, any user in that group will have that permission.
  129. Beyond permissions, groups are a convenient way to categorize users to
  130. apply some label, or extended functionality, to them. For example, you
  131. could create a group 'Special users', and you could write code that would
  132. do special things to those users -- such as giving them access to a
  133. members-only portion of your site, or sending them members-only email
  134. messages.
  135. """
  136. id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
  137. name = models.CharField(_('name'), max_length=80, unique=True)
  138. isActive = models.BooleanField(default=True)
  139. createdAt = models.DateTimeField(auto_now_add=True)
  140. updatedAt = models.DateTimeField(auto_now=True)
  141. permissions = models.ManyToManyField(
  142. Permission,
  143. verbose_name=_('permissions'), blank=True
  144. )
  145. objects = GroupManager()
  146. class Meta:
  147. verbose_name = _('group')
  148. verbose_name_plural = _('groups')
  149. def __str__(self):
  150. return self.name
  151. def natural_key(self):
  152. return (self.name,)
  153. class User(AbstractBaseUser):
  154. id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
  155. username = models.CharField(
  156. max_length=30, unique=True,
  157. help_text=_('Required. 30 characters or fewer. Letters, digits and '
  158. '@/./+/-/_ only.'),
  159. validators=[
  160. validators.RegexValidator(r'^[\w.@+-]+$',
  161. _('Enter a valid username. '
  162. 'This value may contain only letters, numbers '
  163. 'and @/./+/-/_ characters.'), 'invalid'),
  164. ],
  165. error_messages={
  166. 'unique': _("A user with that username already exists."),
  167. }
  168. )
  169. firstName = models.CharField(max_length=30, blank=True)
  170. lastName = models.CharField(max_length=30, blank=True)
  171. email = models.EmailField()
  172. is_staff = models.BooleanField(default=False)
  173. is_active = models.BooleanField(default=True)
  174. date_joined = models.DateTimeField(default=timezone.now)
  175. bio = models.TextField(null=False, blank=True)
  176. photo = models.CharField(max_length=500, null=True, blank=True)
  177. lang = models.CharField(max_length=20, null=True, blank=True, default='', verbose_name=_("default language"))
  178. token = models.CharField(max_length=200, null=True, blank=True, default=None)
  179. emailToken = models.CharField(max_length=200, null=True, blank=True, default=None)
  180. new_email = models.EmailField(null=True, blank=True)
  181. is_system = models.BooleanField(null=False, blank=False, default=False)
  182. ip = models.GenericIPAddressField(null=True, blank=True)
  183. fingerKey = models.CharField(max_length=100, null=True, blank=True)
  184. is_superuser = models.BooleanField(default=False)
  185. groups = models.ManyToManyField(Group, blank=True, related_name="user_set", related_query_name="user")
  186. user_permissions = models.ManyToManyField(Permission, blank=True, related_name="user_set",
  187. related_query_name="user")
  188. site = models.UUIDField(null=True, blank=True)
  189. sites = models.ManyToManyField(Site, blank=True, related_name="user_set", related_query_name="user")
  190. USERNAME_FIELD = 'username'
  191. REQUIRED_FIELDS = ['email', ]
  192. objects = UserManager()
  193. class Meta:
  194. verbose_name = 'user'
  195. verbose_name_plural = 'users'
  196. ordering = ['username']
  197. def __str__(self):
  198. return self.get_full_name()
  199. def get_group_permissions(self, obj=None):
  200. """
  201. Returns a list of permission strings that this user has through their
  202. groups. This method queries all available auth backends. If an object
  203. is passed in, only permissions matching this object are returned.
  204. """
  205. permissions = set()
  206. for backend in auth.get_backends():
  207. if hasattr(backend, "get_group_permissions"):
  208. permissions.update(backend.get_group_permissions(self, obj))
  209. return permissions
  210. def get_all_permissions(self, obj=None):
  211. return _user_get_all_permissions(self, obj)
  212. def has_perm(self, perm, obj=None):
  213. """
  214. Returns True if the user has the specified permission. This method
  215. queries all available auth backends, but returns immediately if any
  216. backend returns True. Thus, a user who has permission from a single
  217. auth backend is assumed to have permission in general. If an object is
  218. provided, permissions for this specific object are checked.
  219. """
  220. # Active superusers have all permissions.
  221. if self.is_active and self.is_superuser:
  222. return True
  223. return _user_has_perm(self, perm, obj)
  224. def has_perms(self, perm_list, obj=None):
  225. """
  226. Returns True if the user has each of the specified permissions. If
  227. object is passed, it checks if the user has all required perms for this
  228. object.
  229. """
  230. for perm in perm_list:
  231. if not self.has_perm(perm, obj):
  232. return False
  233. return True
  234. def has_module_perms(self, app_label):
  235. """
  236. Returns True if the user has any permissions in the given app label.
  237. Uses pretty much the same logic as has_perm, above.
  238. """
  239. # Active superusers have all permissions.
  240. if self.is_active and self.is_superuser:
  241. return True
  242. return _user_has_module_perms(self, app_label)
  243. def get_short_name(self):
  244. """Returns the short name for the user."""
  245. return self.username
  246. def get_full_name(self):
  247. return self.firstName or self.username or self.email
  248. def set_password(self, raw_password):
  249. self.password = make_password(raw_password)
  250. auditlog.register(Site)
  251. auditlog.register(User)