1
# Copyright 2010 Canonical Ltd. This software is licensed under the
2
# GNU Affero General Public License version 3 (see the file LICENSE).
8
from openid.association import Association
10
from openid.store.interface import OpenIDStore
12
from django.conf import settings
13
from django.db import models
14
from django.utils.translation import ugettext_lazy as _
16
from identityprovider.const import NEVER_EXPIRES, SREG_LABELS
17
from identityprovider.readonly import readonly_manager
18
from identityprovider.models import Account
19
from identityprovider.models.const import AccountCreationRationale
23
'OpenIDAuthorization',
31
class OpenIDAssociation(models.Model):
32
server_url = models.CharField(max_length=2047)
33
handle = models.CharField(max_length=255, primary_key=True)
34
secret = models.TextField() # This field type is a guess.
35
issued = models.IntegerField()
36
lifetime = models.IntegerField()
37
assoc_type = models.CharField(max_length=64)
40
app_label = 'identityprovider'
41
db_table = u'openidassociation'
42
unique_together = ('server_url', 'handle')
45
class OpenIDAuthorizationManager(models.Manager):
47
def authorize(self, account, trust_root, expires, client_id=None):
48
if readonly_manager.is_readonly():
51
expires = NEVER_EXPIRES
53
existing = OpenIDAuthorization.objects.get(
56
trust_root=trust_root)
57
existing.date_created = datetime.datetime.utcnow()
58
existing.date_expires = expires
60
except OpenIDAuthorization.DoesNotExist:
61
OpenIDAuthorization.objects.create(
64
trust_root=trust_root,
67
def is_authorized(self, account, trust_root, client_id):
68
client_none = OpenIDAuthorization.objects.filter(
69
account__exact=account,
70
trust_root__exact=trust_root,
71
client_id__exact=None,
72
date_expires__gte=datetime.datetime.utcnow()).count()
76
client_match = OpenIDAuthorization.objects.filter(
77
account__exact=account,
78
trust_root__exact=trust_root,
79
client_id__exact=client_id,
80
date_expires__gte=datetime.datetime.utcnow()).count()
86
class OpenIDAuthorization(models.Model):
87
account = models.ForeignKey(Account, db_column='account')
88
client_id = models.TextField(blank=True, null=True)
89
date_created = models.DateTimeField(default=datetime.datetime.utcnow,
90
blank=True, editable=False)
91
date_expires = models.DateTimeField()
92
trust_root = models.TextField()
94
objects = OpenIDAuthorizationManager()
97
app_label = 'identityprovider'
98
db_table = u'openidauthorization'
101
class OpenIDNonce(models.Model):
102
server_url = models.CharField(max_length=2047, primary_key=True)
103
timestamp = models.IntegerField()
104
salt = models.CharField(max_length=40)
107
app_label = 'identityprovider'
108
db_table = 'openidnonce'
109
unique_together = ('server_url', 'timestamp', 'salt')
112
class OpenIDRPConfig(models.Model):
113
trust_root = models.TextField(unique=True)
114
displayname = models.TextField()
115
description = models.TextField()
116
logo = models.TextField(blank=True, null=True)
117
allowed_sreg = models.TextField(blank=True, null=True,
118
choices=SREG_LABELS.items())
119
creation_rationale = models.IntegerField(default=13,
120
choices=AccountCreationRationale._get_choices())
121
can_query_any_team = models.BooleanField(default=False)
122
auto_authorize = models.BooleanField(default=False)
125
app_label = 'identityprovider'
126
db_table = 'ssoopenidrpconfig'
127
verbose_name = _('OpenID RP Config')
128
verbose_name_plural = _('OpenID RP Configs')
130
def __unicode__(self):
131
return self.displayname
136
return settings.MEDIA_URL + self.logo
141
class OpenIDRPSummaryManager(models.Manager):
143
def record(self, account, trust_root, openid_identifier=None):
144
if readonly_manager.is_readonly():
146
if openid_identifier is None:
147
openid_identifier = account.openid_identity_url
149
summary = OpenIDRPSummary.objects.get(
151
trust_root=trust_root,
152
openid_identifier=openid_identifier)
154
except OpenIDRPSummary.DoesNotExist:
155
summary = OpenIDRPSummary.objects.create(
157
trust_root=trust_root,
158
openid_identifier=openid_identifier)
162
class OpenIDRPSummary(models.Model):
163
account = models.ForeignKey(Account, db_column='account')
164
openid_identifier = models.TextField()
165
trust_root = models.TextField()
166
date_created = models.DateTimeField(default=datetime.datetime.utcnow,
167
blank=True, editable=False)
168
date_last_used = models.DateTimeField(default=datetime.datetime.utcnow,
169
blank=True, editable=False)
170
total_logins = models.IntegerField(default=1)
172
objects = OpenIDRPSummaryManager()
175
app_label = 'identityprovider'
176
db_table = u'openidrpsummary'
177
unique_together = ('account', 'trust_root', 'openid_identifier')
180
self.total_logins += 1
181
self.date_last_used = datetime.datetime.utcnow()
185
class DjangoOpenIDStore(OpenIDStore):
187
The Python openid library needs an OpenIDStore subclass to persist data
188
related to OpenID authentications. This one uses our Django models.
190
From: http://code.google.com/p/django-openid/source/browse/trunk/django_openid/models.py
192
Please see the license file in thirdparty/django-openid.
195
def storeAssociation(self, server_url, association):
197
assoc = OpenIDAssociation.objects.get(
198
server_url=server_url,
199
handle=association.handle)
200
assoc.secret = base64.b64encode(association.secret)
201
assoc.issued = association.issued
202
assoc.lifetime = association.getExpiresIn()
203
assoc.assoc_type = association.assoc_type
204
except OpenIDAssociation.DoesNotExist:
205
assoc = OpenIDAssociation(
206
server_url=server_url,
207
handle=association.handle,
208
secret=base64.b64encode(association.secret),
209
issued=association.issued,
210
lifetime=association.getExpiresIn(),
211
assoc_type=association.assoc_type)
214
def getAssociation(self, server_url, handle=None):
216
if handle is not None:
217
assocs = OpenIDAssociation.objects.filter(
218
server_url=server_url,
222
assocs = OpenIDAssociation.objects.filter(
223
server_url=server_url)
228
association = Association(
229
assoc.handle, base64.b64decode(str(assoc.secret)),
230
assoc.issued, assoc.lifetime, assoc.assoc_type)
231
if association.getExpiresIn() == 0:
232
self.removeAssociation(server_url, assoc.handle)
234
associations.append((association.issued, association))
237
return associations[-1][1]
239
def removeAssociation(self, server_url, handle):
240
assocs = list(OpenIDAssociation.objects.filter(
241
server_url=server_url, handle=handle))
242
assocs_exist = len(assocs) > 0
247
def useNonce(self, server_url, timestamp, salt):
249
if abs(timestamp - time.time()) > openid.store.nonce.SKEW:
252
nonce = OpenIDNonce.objects.get(
253
server_url__exact=server_url,
254
timestamp__exact=timestamp,
256
except OpenIDNonce.DoesNotExist:
257
nonce = OpenIDNonce.objects.create(
258
server_url=server_url,
265
def cleanupNonce(self):
266
OpenIDNonce.objects.filter(
268
int(time.time()) - openid.store.nonce.SKEW)).delete()
270
def cleanupAssociations(self):
271
OpenIDAssociation.objects.extra(
273
'issued + lifetimeint < (%s)' % time.time()]).delete()