Merge branch 'master' into OPW-Moderation-Update
[mediagoblin.git] / mediagoblin / plugins / openid / store.py
CommitLineData
5adb906a
RE
1# GNU MediaGoblin -- federated, autonomous media hosting
2# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU Affero General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16import base64
17import time
18
19from openid.association import Association as OIDAssociation
20from openid.store.interface import OpenIDStore
21from openid.store import nonce
22
23from mediagoblin.plugins.openid.models import Association, Nonce
24
25
26class SQLAlchemyOpenIDStore(OpenIDStore):
27 def __init__(self):
28 self.max_nonce_age = 6 * 60 * 60
29
30 def storeAssociation(self, server_url, association):
31 assoc = Association.query.filter_by(
32 server_url=server_url, handle=association.handle
33 ).first()
34
35 if not assoc:
36 assoc = Association()
37 assoc.server_url = unicode(server_url)
38 assoc.handle = association.handle
39
40 # django uses base64 encoding, python-openid uses a blob field for
41 # secret
42 assoc.secret = unicode(base64.encodestring(association.secret))
43 assoc.issued = association.issued
44 assoc.lifetime = association.lifetime
45 assoc.assoc_type = association.assoc_type
46 assoc.save()
47
48 def getAssociation(self, server_url, handle=None):
49 assocs = []
50 if handle is not None:
51 assocs = Association.query.filter_by(
52 server_url=server_url, handle=handle
53 )
54 else:
55 assocs = Association.query.filter_by(
56 server_url=server_url
57 )
58
59 if assocs.count() == 0:
60 return None
61 else:
62 associations = []
63 for assoc in assocs:
64 association = OIDAssociation(
65 assoc.handle, base64.decodestring(assoc.secret),
66 assoc.issued, assoc.lifetime, assoc.assoc_type
67 )
68 if association.getExpiresIn() == 0:
69 assoc.delete()
70 else:
71 associations.append((association.issued, association))
72
73 if not associations:
74 return None
75 associations.sort()
76 return associations[-1][1]
77
78 def removeAssociation(self, server_url, handle):
79 assocs = Association.query.filter_by(
80 server_url=server_url, handle=handle
81 ).first()
82
83 assoc_exists = True if assocs else False
84 for assoc in assocs:
85 assoc.delete()
86 return assoc_exists
87
88 def useNonce(self, server_url, timestamp, salt):
89 if abs(timestamp - time.time()) > nonce.SKEW:
90 return False
91
92 ononce = Nonce.query.filter_by(
93 server_url=server_url,
94 timestamp=timestamp,
95 salt=salt
96 ).first()
97
98 if ononce:
99 return False
100 else:
101 ononce = Nonce()
102 ononce.server_url = server_url
103 ononce.timestamp = timestamp
104 ononce.salt = salt
105 ononce.save()
106 return True
107
5adb906a
RE
108 def cleanupNonces(self, _now=None):
109 if _now is None:
110 _now = int(time.time())
111 expired = Nonce.query.filter(
112 Nonce.timestamp < (_now - nonce.SKEW)
113 )
114 count = expired.count()
115 for each in expired:
116 each.delete()
117 return count
118
119 def cleanupAssociations(self):
120 now = int(time.time())
664ce3bf
RE
121 assoc = Association.query.all()
122 count = 0
123 for each in assoc:
124 if (each.lifetime + each.issued) <= now:
125 each.delete()
126 count = count + 1
5adb906a 127 return count