Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / models.py @ f534fb96

History | View | Annotate | Download (5.8 kB)

1 aba1e498 Antony Chazapis
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2 64cd4730 Antony Chazapis
# 
3 64cd4730 Antony Chazapis
# Redistribution and use in source and binary forms, with or
4 64cd4730 Antony Chazapis
# without modification, are permitted provided that the following
5 64cd4730 Antony Chazapis
# conditions are met:
6 64cd4730 Antony Chazapis
# 
7 64cd4730 Antony Chazapis
#   1. Redistributions of source code must retain the above
8 64cd4730 Antony Chazapis
#      copyright notice, this list of conditions and the following
9 64cd4730 Antony Chazapis
#      disclaimer.
10 64cd4730 Antony Chazapis
# 
11 64cd4730 Antony Chazapis
#   2. Redistributions in binary form must reproduce the above
12 64cd4730 Antony Chazapis
#      copyright notice, this list of conditions and the following
13 64cd4730 Antony Chazapis
#      disclaimer in the documentation and/or other materials
14 64cd4730 Antony Chazapis
#      provided with the distribution.
15 64cd4730 Antony Chazapis
# 
16 64cd4730 Antony Chazapis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 64cd4730 Antony Chazapis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 64cd4730 Antony Chazapis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 64cd4730 Antony Chazapis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 64cd4730 Antony Chazapis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 64cd4730 Antony Chazapis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 64cd4730 Antony Chazapis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 64cd4730 Antony Chazapis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 64cd4730 Antony Chazapis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 64cd4730 Antony Chazapis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 64cd4730 Antony Chazapis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 64cd4730 Antony Chazapis
# POSSIBILITY OF SUCH DAMAGE.
28 64cd4730 Antony Chazapis
# 
29 64cd4730 Antony Chazapis
# The views and conclusions contained in the software and
30 64cd4730 Antony Chazapis
# documentation are those of the authors and should not be
31 64cd4730 Antony Chazapis
# interpreted as representing official policies, either expressed
32 64cd4730 Antony Chazapis
# or implied, of GRNET S.A.
33 64cd4730 Antony Chazapis
34 64cd4730 Antony Chazapis
import hashlib
35 15efc749 Sofia Papagiannaki
import uuid
36 64cd4730 Antony Chazapis
37 64cd4730 Antony Chazapis
from time import asctime
38 64cd4730 Antony Chazapis
from datetime import datetime, timedelta
39 64cd4730 Antony Chazapis
from base64 import b64encode
40 64cd4730 Antony Chazapis
41 64cd4730 Antony Chazapis
from django.db import models
42 0905ccd2 Sofia Papagiannaki
from django.contrib.auth.models import User, UserManager
43 64cd4730 Antony Chazapis
44 92defad4 Sofia Papagiannaki
from astakos.im.settings import DEFAULT_USER_LEVEL, INVITATIONS_PER_LEVEL, AUTH_TOKEN_DURATION
45 64cd4730 Antony Chazapis
46 0905ccd2 Sofia Papagiannaki
class AstakosUser(User):
47 890b0eaf Sofia Papagiannaki
    """
48 890b0eaf Sofia Papagiannaki
    Extends ``django.contrib.auth.models.User`` by defining additional fields.
49 890b0eaf Sofia Papagiannaki
    """
50 0905ccd2 Sofia Papagiannaki
    # Use UserManager to get the create_user method, etc.
51 0905ccd2 Sofia Papagiannaki
    objects = UserManager()
52 64cd4730 Antony Chazapis
    
53 5ed6816e Sofia Papagiannaki
    affiliation = models.CharField('Affiliation', max_length=255, blank=True)
54 5ed6816e Sofia Papagiannaki
    provider = models.CharField('Provider', max_length=255, blank=True)
55 64cd4730 Antony Chazapis
    
56 64cd4730 Antony Chazapis
    #for invitations
57 92defad4 Sofia Papagiannaki
    user_level = DEFAULT_USER_LEVEL
58 a196eb7e Sofia Papagiannaki
    level = models.IntegerField('Inviter level', default=user_level)
59 8316698a Sofia Papagiannaki
    invitations = models.IntegerField('Invitations left', default=INVITATIONS_PER_LEVEL.get(user_level, 0))
60 64cd4730 Antony Chazapis
    
61 64cd4730 Antony Chazapis
    auth_token = models.CharField('Authentication Token', max_length=32,
62 0905ccd2 Sofia Papagiannaki
                                  null=True, blank=True)
63 0905ccd2 Sofia Papagiannaki
    auth_token_created = models.DateTimeField('Token creation date', null=True)
64 0905ccd2 Sofia Papagiannaki
    auth_token_expires = models.DateTimeField('Token expiration date', null=True)
65 64cd4730 Antony Chazapis
    
66 64cd4730 Antony Chazapis
    updated = models.DateTimeField('Update date')
67 890b0eaf Sofia Papagiannaki
    is_verified = models.BooleanField('Is verified?', default=False)
68 64cd4730 Antony Chazapis
    
69 15efc749 Sofia Papagiannaki
    # ex. screen_name for twitter, eppn for shibboleth
70 15efc749 Sofia Papagiannaki
    third_party_identifier = models.CharField('Third-party identifier', max_length=255, null=True, blank=True)
71 15efc749 Sofia Papagiannaki
    
72 8316698a Sofia Papagiannaki
    email_verified = models.BooleanField('Email verified?', default=False)
73 8316698a Sofia Papagiannaki
    
74 0905ccd2 Sofia Papagiannaki
    @property
75 0905ccd2 Sofia Papagiannaki
    def realname(self):
76 0905ccd2 Sofia Papagiannaki
        return '%s %s' %(self.first_name, self.last_name)
77 64cd4730 Antony Chazapis
    
78 0905ccd2 Sofia Papagiannaki
    @realname.setter
79 0905ccd2 Sofia Papagiannaki
    def realname(self, value):
80 0905ccd2 Sofia Papagiannaki
        parts = value.split(' ')
81 0905ccd2 Sofia Papagiannaki
        if len(parts) == 2:
82 0905ccd2 Sofia Papagiannaki
            self.first_name = parts[0]
83 0905ccd2 Sofia Papagiannaki
            self.last_name = parts[1]
84 0905ccd2 Sofia Papagiannaki
        else:
85 0905ccd2 Sofia Papagiannaki
            self.last_name = parts[0]
86 64cd4730 Antony Chazapis
    
87 64cd4730 Antony Chazapis
    @property
88 64cd4730 Antony Chazapis
    def invitation(self):
89 64cd4730 Antony Chazapis
        try:
90 9fb8e808 Sofia Papagiannaki
            return Invitation.objects.get(username=self.email)
91 64cd4730 Antony Chazapis
        except Invitation.DoesNotExist:
92 64cd4730 Antony Chazapis
            return None
93 64cd4730 Antony Chazapis
    
94 64cd4730 Antony Chazapis
    def save(self, update_timestamps=True, **kwargs):
95 64cd4730 Antony Chazapis
        if update_timestamps:
96 64cd4730 Antony Chazapis
            if not self.id:
97 a196eb7e Sofia Papagiannaki
                # set username
98 15efc749 Sofia Papagiannaki
                while not self.username:
99 15efc749 Sofia Papagiannaki
                    username =  uuid.uuid4().hex[:30]
100 15efc749 Sofia Papagiannaki
                    try:
101 15efc749 Sofia Papagiannaki
                        AstakosUser.objects.get(username = username)
102 15efc749 Sofia Papagiannaki
                    except AstakosUser.DoesNotExist, e:
103 15efc749 Sofia Papagiannaki
                        self.username = username
104 15efc749 Sofia Papagiannaki
                self.is_active = False
105 15efc749 Sofia Papagiannaki
                if not self.provider:
106 15efc749 Sofia Papagiannaki
                    self.provider = 'local'
107 0905ccd2 Sofia Papagiannaki
                self.date_joined = datetime.now()
108 64cd4730 Antony Chazapis
            self.updated = datetime.now()
109 0905ccd2 Sofia Papagiannaki
        super(AstakosUser, self).save(**kwargs)
110 64cd4730 Antony Chazapis
    
111 64cd4730 Antony Chazapis
    def renew_token(self):
112 64cd4730 Antony Chazapis
        md5 = hashlib.md5()
113 0905ccd2 Sofia Papagiannaki
        md5.update(self.username)
114 64cd4730 Antony Chazapis
        md5.update(self.realname.encode('ascii', 'ignore'))
115 64cd4730 Antony Chazapis
        md5.update(asctime())
116 64cd4730 Antony Chazapis
        
117 64cd4730 Antony Chazapis
        self.auth_token = b64encode(md5.digest())
118 64cd4730 Antony Chazapis
        self.auth_token_created = datetime.now()
119 64cd4730 Antony Chazapis
        self.auth_token_expires = self.auth_token_created + \
120 92defad4 Sofia Papagiannaki
                                  timedelta(hours=AUTH_TOKEN_DURATION)
121 64cd4730 Antony Chazapis
    
122 64cd4730 Antony Chazapis
    def __unicode__(self):
123 0905ccd2 Sofia Papagiannaki
        return self.username
124 64cd4730 Antony Chazapis
125 64cd4730 Antony Chazapis
class Invitation(models.Model):
126 890b0eaf Sofia Papagiannaki
    """
127 890b0eaf Sofia Papagiannaki
    Model for registring invitations
128 890b0eaf Sofia Papagiannaki
    """
129 0905ccd2 Sofia Papagiannaki
    inviter = models.ForeignKey(AstakosUser, related_name='invitations_sent',
130 64cd4730 Antony Chazapis
                                null=True)
131 64cd4730 Antony Chazapis
    realname = models.CharField('Real name', max_length=255)
132 8316698a Sofia Papagiannaki
    username = models.CharField('Unique ID', max_length=255, unique=True)
133 64cd4730 Antony Chazapis
    code = models.BigIntegerField('Invitation code', db_index=True)
134 64cd4730 Antony Chazapis
    #obsolete: we keep it just for transfering the data
135 64cd4730 Antony Chazapis
    is_accepted = models.BooleanField('Accepted?', default=False)
136 64cd4730 Antony Chazapis
    is_consumed = models.BooleanField('Consumed?', default=False)
137 64cd4730 Antony Chazapis
    created = models.DateTimeField('Creation date', auto_now_add=True)
138 64cd4730 Antony Chazapis
    #obsolete: we keep it just for transfering the data
139 64cd4730 Antony Chazapis
    accepted = models.DateTimeField('Acceptance date', null=True, blank=True)
140 64cd4730 Antony Chazapis
    consumed = models.DateTimeField('Consumption date', null=True, blank=True)
141 64cd4730 Antony Chazapis
    
142 64cd4730 Antony Chazapis
    def consume(self):
143 64cd4730 Antony Chazapis
        self.is_consumed = True
144 64cd4730 Antony Chazapis
        self.consumed = datetime.now()
145 64cd4730 Antony Chazapis
        self.save()
146 64cd4730 Antony Chazapis
        
147 64cd4730 Antony Chazapis
    def __unicode__(self):
148 0905ccd2 Sofia Papagiannaki
        return '%s -> %s [%d]' % (self.inviter, self.username, self.code)