models.py 5.71 KB
Newer Older
1
import re
2
import validators
3
from django.conf import settings
4
from django.core.validators import RegexValidator
5
from django.contrib.auth.models import AbstractUser
6
from django.db import models
7
from django.db.models.signals import post_save, pre_save
8
from django.dispatch import receiver
9
from django.urls import reverse_lazy
10
from django.utils.deconstruct import deconstructible
11
from django.utils.translation import ugettext_lazy as _
12 13
from importlib import import_module

14

15 16
from djangoldp.models import Model

17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
from djangoldp.permissions import LDPPermissions

djangoldp_modules = list(settings.DJANGOLDP_PACKAGES)
user_fields = ['@id', 'first_name', 'groups', 'last_name', 'username', 'email', 'account', 'chatProfile', 'name']
user_nested_fields = ['account', 'groups', 'chatProfile']
for dldp_module in djangoldp_modules:
    try:
        module_user_nested_fields = import_module(dldp_module + '.settings').USER_NESTED_FIELDS
        user_fields += module_user_nested_fields
        user_nested_fields += module_user_nested_fields
    except:
        pass

s_fields = []
s_fields.extend(user_fields)
s_fields.extend(user_nested_fields)
33

34

35 36 37 38 39 40 41 42 43 44
@deconstructible
class UsernameValidator(RegexValidator):
    regex = r'^[\w.+-]+$'
    message = _(
        'Enter a valid username. This value may contain only letters, '
        'numbers, and ./+/-/_ characters.'
    )
    flags = re.UNICODE


45 46
class LDPUser(AbstractUser, Model):
    slug = models.SlugField(unique=True, blank=True, null=True)
47 48 49 50 51 52 53 54 55 56 57
    username_validator = UsernameValidator()
    username = models.CharField(
        _('username'),
        max_length=150,
        unique=True,
        help_text=_('Required. 150 characters or fewer. Letters, digits and ./+/-/_ only.'),
        validators=[username_validator],
        error_messages={
            'unique': _("A user with that username already exists."),
        },
    )
58 59 60 61 62 63 64 65
    email = models.EmailField(
        _('email address'),
        blank=True,
        unique=True,
        error_messages={
            'unique': _("A user with that uses this email address already exists."),
        },
    )
Calum Mackervoy's avatar
Calum Mackervoy committed
66
    # updated automatically on login - the default uri to redirect to if none has been passed
67
    default_redirect_uri = models.CharField(max_length=5000, blank=True, null=True, help_text='A URL to redirect to (home page) when none other is provided in a request, e.g. on forgot password. This will be automatically updated on login')
68

69 70 71 72 73
    class Meta:
        verbose_name = _('user')
        verbose_name_plural = _('users')
        rdf_type = 'foaf:user'
        lookup_field = 'slug'
74
        container_path = 'users'
Jean-Baptiste's avatar
Jean-Baptiste committed
75
        owner_field = 'urlid'
76 77
        permission_classes = getattr(settings, 'USER_PERMISSION_CLASSES', [LDPPermissions])
        nested_fields = user_nested_fields
78 79 80 81
        serializer_fields = s_fields
        anonymous_perms = getattr(settings, 'USER_ANONYMOUS_PERMISSIONS', ['view'])
        authenticated_perms = getattr(settings, 'USER_AUTHENTICATED_PERMISSIONS', ['inherit'])
        owner_perms = getattr(settings, 'USER_OWNER_PERMISSIONS', ['inherit'])
82

83 84
    def name(self):
        return self.get_full_name()
85

86 87 88 89 90
    def webid(self):
        # hack : We user webid as username for external user (since it's an uniq identifier too)
        if validators.url(self.username):
            webid = self.username
        else:
91
            webid = '{0}{1}'.format(settings.BASE_URL, reverse_lazy('ldpuser-detail', kwargs={'slug': self.slug}))
92
        return webid
93 94


95
class Account(Model):
96
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
97
    slug = models.SlugField(unique=True)
98
    picture = models.URLField(blank=True, null=True)
99
    issuer = models.URLField(blank=True, null=True)
100 101

    class Meta:
102
        auto_author = 'user'
103 104 105 106
        permissions = (
            ('view_account', 'Read'),
            ('control_account', 'Control'),
        )
Gaëlle Morin's avatar
Gaëlle Morin committed
107
        rdf_context = {'picture': 'foaf:depiction'}
108
        lookup_field = 'slug'
109 110 111 112

    def __str__(self):
        return '{} ({})'.format(self.user.get_full_name(), self.user.username)

113

114
class ChatProfile(Model):
115
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="chatProfile")
116
    slug = models.SlugField(unique=True)
117
    jabberID = models.CharField(max_length=255, blank=True, null=True)
118 119

    class Meta:
120
        auto_author = 'user'
121 122 123 124
        permissions = (
            ('view_chatprofile', 'Read'),
            ('control_chatprofile', 'Control'),
        )
125
        lookup_field = 'slug'
126 127

    def __str__(self):
Jean-Baptiste's avatar
Jean-Baptiste committed
128
        return '{} (jabberID: {})'.format(self.user.get_full_name(), self.jabberID)
129 130


131
class OPClient(Model):
132 133
    issuer = models.URLField()
    client_id = models.CharField(max_length=255)
134 135 136 137
    client_secret = models.CharField(max_length=255)

    def __str__(self):
        return '{} ({})'.format(self.issuer, self.client_id)
138 139


140 141 142 143 144 145
@receiver(pre_save, sender=settings.AUTH_USER_MODEL)
def pre_create_account(sender, instance, **kwargs):
    if getattr(instance, Model.slug_field(instance)) != instance.username:
        setattr(instance, Model.slug_field(instance), instance.username)


146
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
147 148
def create_account(sender, instance, created, **kwargs):
    if created:
149 150
        Account.objects.create(user=instance, slug=instance.username)
        chat_profile = ChatProfile.objects.create(user=instance, slug=instance.username)
151 152 153
        if settings.JABBER_DEFAULT_HOST:
            chat_profile.jabberID = '{}@{}'.format(instance.username, settings.JABBER_DEFAULT_HOST)
            chat_profile.save()
Jean-Baptiste's avatar
Jean-Baptiste committed
154 155
    else:
        try:
156 157 158 159
            instance.account.slug = instance.username
            instance.account.save()
            instance.chatProfile.slug = instance.username
            instance.chatProfile.save()
160 161
        except:
            pass