1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """
23 serializable keycards used for authentication
24 """
25
26 from twisted.cred.credentials import ICredentials
27 from twisted.spread import pb
28 from zope.interface import implements
29
30 from flumotion.twisted import credentials
31
32 __version__ = "$Rev: 6968 $"
33 _statesEnum = ['REFUSED', 'REQUESTING', 'AUTHENTICATED']
34
35 (REFUSED,
36 REQUESTING,
37 AUTHENTICATED) = range(3)
38
39
40 -class Keycard(pb.Copyable, pb.RemoteCopy):
41 """
42 I am the base class for keycards which together with credentials are
43 a serializable object used in authentication inside Flumotion.
44
45 @ivar bouncerName: name of the bouncer to authenticate against; set by
46 requester
47 @type bouncerName: str
48 @ivar requesterId: avatarId of the requester
49 @type requesterId: str
50 @ivar avatarId: avatarId preferred by requester
51 @type avatarId: str
52 @ivar id: id of keycard decided by bouncer after authenticating
53 @type id: object
54 @ivar duration: duration for which the keycard is valid, or 0 for
55 unlimited
56 @type duration: int
57 @ivar domain: requester can pass a domain id to the bouncer
58 @type domain: str
59 @ivar state: state the keycard is in
60 @type state: int
61 """
62 implements(ICredentials)
63
72
73
74 - def setDomain(self, domain):
75 """
76 Set the domain of the requester on the keycard.
77
78 @type domain: string
79 """
80 import warnings
81 warnings.warn('Set the domain on the keycard directly.',
82 DeprecationWarning, stacklevel=2)
83
84 self.domain = domain
85
87 """
88 Return a dictionary of the viewable data on the keycard that can be
89 used to identify the keycard.
90 It doesn't include sensitive information though.
91
92 Subclasses should override to add additional information.
93 """
94 return {
95 'id': self.id,
96 'requester': self.requesterId,
97 'domain': self.domain
98 }
99
101 return "<%s for requesterId %r in state %s>" % (self.__class__.__name__,
102 self.requesterId, _statesEnum[self.state])
103
106
107 pb.setUnjellyableForClass(KeycardGeneric, KeycardGeneric)
108
109
110
111
112 UCPP = credentials.UsernameCryptPasswordPlaintext
114 """
115 I am a keycard with a username, plaintext password and IP address.
116 I get authenticated against a crypt password.
117 """
118 - def __init__(self, username, password, address):
122
128
133
134 pb.setUnjellyableForClass(KeycardUACPP, KeycardUACPP)
135
136
137
138
139
140 UCPCC = credentials.UsernameCryptPasswordCryptChallenger
142 """
143 I am a keycard with a username and IP address.
144 I get authenticated through challenge/response on a crypt password.
145 """
150
156
161
162 pb.setUnjellyableForClass(KeycardUACPCC, KeycardUACPCC)
163
164
166 """
167 I am a keycard with a token and IP address and a path (optional).
168 I get authenticated by token and maybe IP address.
169 """
170
171 - def __init__(self, token, address, path=None):
176
178 d = Keycard.getData(self)
179 d['token'] = self.token
180 d['address'] = self.address
181 d['path'] = self.path
182 return d
183
185 return "<%s %s token %s for path %s @%s for requesterId %r in state %s>" % (
186 self.__class__.__name__, self.id, self.token, self.path,
187 self.address, self.requesterId, _statesEnum[self.state])
188
189 pb.setUnjellyableForClass(KeycardToken, KeycardToken)
190
191
192 USPCC = credentials.UsernameSha256PasswordCryptChallenger
194 """
195 I am a keycard with a username and IP address.
196 I get authenticated through challenge/response on a SHA-256 password.
197 """
202
208
213
214 pb.setUnjellyableForClass(KeycardUASPCC, KeycardUASPCC)
215
216
232
233 pb.setUnjellyableForClass(KeycardHTTPDigest, KeycardHTTPDigest)
234
235
236
243
244 pb.setUnjellyableForClass(HTTPDigestKeycard, HTTPDigestKeycard)
245