File: memstore.py

package info (click to toggle)
python3-openid 3.0.2%2Bgit20140828-1
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 1,672 kB
  • ctags: 2,679
  • sloc: python: 17,137; xml: 234; sh: 15; makefile: 4
file content (125 lines) | stat: -rw-r--r-- 3,586 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
"""A simple store using only in-process memory."""

from openid.store import nonce

import copy
import time


class ServerAssocs(object):
    def __init__(self):
        self.assocs = {}

    def set(self, assoc):
        self.assocs[assoc.handle] = assoc

    def get(self, handle):
        return self.assocs.get(handle)

    def remove(self, handle):
        try:
            del self.assocs[handle]
        except KeyError:
            return False
        else:
            return True

    def best(self):
        """Returns association with the oldest issued date.

        or None if there are no associations.
        """
        best = None
        for assoc in list(self.assocs.values()):
            if best is None or best.issued < assoc.issued:
                best = assoc
        return best

    def cleanup(self):
        """Remove expired associations.

        @return: tuple of (removed associations, remaining associations)
        """
        remove = []
        for handle, assoc in self.assocs.items():
            if assoc.expiresIn == 0:
                remove.append(handle)
        for handle in remove:
            del self.assocs[handle]
        return len(remove), len(self.assocs)


class MemoryStore(object):
    """In-process memory store.

    Use for single long-running processes.  No persistence supplied.
    """
    def __init__(self):
        self.server_assocs = {}
        self.nonces = {}

    def _getServerAssocs(self, server_url):
        try:
            return self.server_assocs[server_url]
        except KeyError:
            assocs = self.server_assocs[server_url] = ServerAssocs()
            return assocs

    def storeAssociation(self, server_url, assoc):
        assocs = self._getServerAssocs(server_url)
        assocs.set(copy.deepcopy(assoc))

    def getAssociation(self, server_url, handle=None):
        assocs = self._getServerAssocs(server_url)
        if handle is None:
            return assocs.best()
        else:
            return assocs.get(handle)

    def removeAssociation(self, server_url, handle):
        assocs = self._getServerAssocs(server_url)
        return assocs.remove(handle)

    def useNonce(self, server_url, timestamp, salt):
        if abs(timestamp - time.time()) > nonce.SKEW:
            return False

        anonce = (str(server_url), int(timestamp), str(salt))
        if anonce in self.nonces:
            return False
        else:
            self.nonces[anonce] = None
            return True

    def cleanupNonces(self):
        now = time.time()
        expired = []
        for anonce in self.nonces.keys():
            if abs(anonce[1] - now) > nonce.SKEW:
                # removing items while iterating over the set could be bad.
                expired.append(anonce)

        for anonce in expired:
            del self.nonces[anonce]
        return len(expired)

    def cleanupAssociations(self):
        remove_urls = []
        removed_assocs = 0
        for server_url, assocs in self.server_assocs.items():
            removed, remaining = assocs.cleanup()
            removed_assocs += removed
            if not remaining:
                remove_urls.append(server_url)

        # Remove entries from server_assocs that had none remaining.
        for server_url in remove_urls:
            del self.server_assocs[server_url]
        return removed_assocs

    def __eq__(self, other):
        return ((self.server_assocs == other.server_assocs) and
                (self.nonces == other.nonces))

    def __ne__(self, other):
        return not (self == other)