models.py 4.19 KB
Newer Older
1
from itertools import chain
2 3
from logging import getLogger

4
from django.conf import settings
5
from django.contrib.auth.models import User, Group
6
from django.contrib.auth.signals import user_logged_in
7
from django.db.models import (
8
    Model, ForeignKey, OneToOneField, CharField, IntegerField, TextField
9
)
10
from django.utils.translation import ugettext_lazy as _
11 12

from vm.models import Instance
13
from acl.models import AclBase
14

15 16
logger = getLogger(__name__)

17

18 19 20
class Favourite(Model):
    instance = ForeignKey(Instance)
    user = ForeignKey(User)
21 22 23 24 25 26 27 28 29 30 31


class Profile(Model):
    user = OneToOneField(User)
    preferred_language = CharField(verbose_name=_('preferred language'),
                                   choices=settings.LANGUAGES,
                                   max_length=32,
                                   default=settings.LANGUAGE_CODE, blank=False)
    org_id = CharField(  # may be populated from eduPersonOrgId field
        unique=True, blank=True, null=True, max_length=64,
        help_text=_('Unique identifier of the person, e.g. a student number.'))
32
    instance_limit = IntegerField(default=5)
33 34


35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
class GroupProfile(AclBase):
    ACL_LEVELS = (
        ('operator', _('operator')),
        ('owner', _('owner')),
    )

    group = OneToOneField(Group)
    org_id = CharField(
        unique=True, blank=True, null=True, max_length=64,
        help_text=_('Unique identifier of the group at the organization.'))
    description = TextField()

    @classmethod
    def search(cls, name):
        try:
            return cls.objects.get(org_id=name).group
        except cls.DoesNotExist:
            return Group.objects.get(name=name)


def get_or_create_profile(self):
56
    obj, created = GroupProfile.objects.get_or_create(group_id=self.pk)
57 58 59 60 61
    return obj

Group.profile = property(get_or_create_profile)


62
def create_profile(sender, user, request, **kwargs):
63 64
    if not user.pk:
        return False
65 66 67 68 69
    profile, created = Profile.objects.get_or_create(user=user)
    return created

user_logged_in.connect(create_profile)

70
if hasattr(settings, 'SAML_ORG_ID_ATTRIBUTE'):
71
    logger.debug("Register save_org_id to djangosaml2 pre_user_save")
72 73
    from djangosaml2.signals import pre_user_save

74
    def save_org_id(sender, **kwargs):
75
        logger.debug("save_org_id called by %s", sender.username)
76
        attributes = kwargs.pop('attributes')
77
        atr = settings.SAML_ORG_ID_ATTRIBUTE
78 79 80 81 82 83
        try:
            value = attributes[atr][0]
        except Exception as e:
            value = None
            logger.info("save_org_id couldn't find attribute. %s", unicode(e))

84 85 86 87
        if sender.pk is None:
            sender.save()
            logger.debug("save_org_id saved user %s", unicode(sender))

88 89
        profile, created = Profile.objects.get_or_create(user=sender)
        if created or profile.org_id != value:
90 91
            logger.info("org_id of %s added to user %s's profile",
                        value, sender.username)
92 93
            profile.org_id = value
            profile.save()
94 95 96
        else:
            logger.debug("org_id of %s already added to user %s's profile",
                         value, sender.username)
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
        memberatrs = getattr(settings, 'SAML_GROUP_ATTRIBUTES', [])
        for group in chain(*[attributes[i] for i in memberatrs]):
            try:
                g = GroupProfile.search(group)
            except Group.DoesNotExist:
                logger.debug('cant find membergroup %s', group)
            else:
                logger.debug('could find membergroup %s (%s)',
                             group, unicode(g))
                g.user_set.add(sender)

        owneratrs = getattr(settings, 'SAML_GROUP_OWNER_ATTRIBUTES', [])
        for group in chain(*[attributes[i] for i in owneratrs]):
            try:
                g = GroupProfile.search(group)
            except Group.DoesNotExist:
                logger.debug('cant find ownergroup %s', group)
            else:
                logger.debug('could find ownergroup %s (%s)',
                             group, unicode(g))
                g.profile.set_level(sender, 'owner')

        return False  # User did not change
120

121 122
    pre_user_save.connect(save_org_id)

123 124
else:
    logger.debug("Do not register save_org_id to djangosaml2 pre_user_save")