1 # -*- coding: utf-8 -*-
3 # Copyright 2010 Maurizio Porrato <maurizio.porrato@gmail.com>
4 # See LICENSE.txt for copyright info
7 from twisted
.python
import log
8 from frn
.user
import FRNUser
10 CLIENTS_ORDER
= ['Crosslink', 'Parrot', 'Gateway', 'PC Only']
14 ta
= CLIENTS_ORDER
.index(a
.BC
)
16 ta
= CLIENTS_ORDER
.index('Gateway')
18 tb
= CLIENTS_ORDER
.index(b
.BC
)
20 tb
= CLIENTS_ORDER
.index('Gateway')
35 class ClientTracker(object):
37 def __init__(self
, filename
, cbClient
, cbNet
, cbMute
, cbBlock
, cbAdmin
):
44 self
.cbClient
= cbClient
47 self
.cbBlock
= cbBlock
48 self
.cbAdmin
= cbAdmin
49 self
.filename
= filename
52 def load(self
, filename
=None):
53 s
= shelve
.open(filename
or self
.filename
)
55 self
._mute
= s
['mute']
56 self
._block
= s
['block']
57 self
._admin
= s
['admin']
62 def save(self
, filename
=None):
63 s
= shelve
.open(filename
or self
.filename
)
64 s
['mute'] = self
._mute
65 s
['block'] = self
._block
66 s
['admin'] = self
._admin
70 def isLoggedIn(self
, clientId
):
71 return clientId
in self
._clientData
73 def getClient(self
, clientId
):
74 return self
._clientData
[clientId
].user
76 def getClientProtocol(self
, clientId
):
77 return self
._clientData
[clientId
]
79 def getClientIndex(self
, clientId
):
80 net
= self
.getClient(clientId
).NT
81 l
= [x
.ID
for x
in self
.getClientList(net
)]
82 return l
.index(clientId
)+1
84 def getNetworkList(self
):
85 return sorted(set(self
._net
.keys())|
set(self
._acl
.keys()))
87 def getClientList(self
, network
=[]):
89 allClients
= self
._net
.get(network
, [])
91 allClients
= self
._clientData
.keys()
92 return [self
._clientData
[x
].user
95 def getMuteList(self
, network
=[]):
97 return [x
for x
in self
._mute
.values()
98 if self
._mute
[x
.ID
].NT
in network
]
100 return [x
for x
in self
._mute
.values()]
102 def getBlockList(self
):
103 return self
._block
.values()
105 def getAdminList(self
):
106 return self
._admin
.values()
108 def isMute(self
, clientId
):
109 return clientId
in self
._mute
111 def isBlocked(self
, clientId
):
112 return clientId
in self
._block
114 def isAdmin(self
, clientId
):
115 return clientId
in self
._admin
117 def login(self
, client
, status
=0):
118 clientId
= client
.user
.ID
119 if clientId
not in self
._clientData
:
120 if not self
.aclTalkOk(client
.user
.NT
, client
.user
.EA
) and status
< 1:
123 client
.user
.S
= status
124 self
._clientData
[clientId
] = client
126 nc
= self
._net
.get(net
, [])
128 for i
, c
in enumerate(nc
):
129 if client_cmp(client
.user
, self
._clientData
[c
].user
) < 0:
134 nc
.insert(ni
, clientId
)
136 if clientId
in self
._mute
:
138 a
= self
._mute
[clientId
].AI
139 self
._mute
[clientId
].update(**client
.user
.dict())
140 self
._mute
[clientId
].AI
= a
143 if not self
.canLogin(client
.user
):
144 client
.role
= "BLOCK"
146 self
.aclUpdate(client
.user
)
147 if client
.user
.EA
in self
._admin
:
148 client
.role
= "ADMIN"
149 self
._admin
[client
.user
.EA
].update(client
.user
.dict())
152 self
.cbNet(self
.getNetworkList())
153 self
.cbClient(net
, self
.getClientList(net
))
155 def logout(self
, client
):
156 if client
.user
is None:
158 clientId
= client
.user
.ID
159 log
.msg("Client logout: %s" % (clientId
,))
160 if clientId
in self
._clientData
:
161 del self
._clientData
[clientId
]
163 self
._net
[net
].remove(clientId
)
164 if not self
._net
[net
]:
166 self
.cbNet(self
.getNetworkList())
168 self
.cbClient(net
, self
.getClientList(net
))
170 def setStatus(self
, clientId
, status
):
171 user
= self
.getClient(clientId
)
173 if not self
.aclTalkOk(user
.NT
, user
.EA
) and status
< 1:
175 if oldStatus
!= str(status
):
176 self
._clientData
[clientId
].user
.S
= status
177 self
.cbClient(user
.NT
, self
.getClientList(user
.NT
))
179 def mute(self
, admin
, clientId
):
180 if clientId
not in self
._mute
:
181 self
._mute
[clientId
] = self
.getClient(clientId
).copy(AI
=admin
.ON
)
182 self
._clientData
[clientId
].user
.M
= 1
184 net
= self
.getClient(clientId
).NT
185 self
.cbClient(net
, self
.getClientList(net
))
186 self
.cbMute(self
.getMuteList())
188 def unMute(self
, clientId
):
189 if clientId
in self
._mute
:
190 del self
._mute
[clientId
]
191 if clientId
in self
._clientData
:
192 self
._clientData
[clientId
].user
.M
= 0
193 net
= self
._clientData
[clientId
].user
.NT
194 self
.cbClient(net
, self
.getClientList(net
))
196 self
.cbMute(self
.getMuteList())
198 def block(self
, admin
, clientId
):
199 if clientId
not in self
._block
:
200 self
._block
[clientId
] = self
.getClient(clientId
).copy(AI
=admin
.ON
)
201 if clientId
in self
._clientData
:
202 net
= self
._clientData
[clientId
].user
.NT
204 self
.cbBlock(self
.getBlockList())
206 def unBlock(self
, clientId
):
207 if clientId
in self
._block
:
208 del self
._block
[clientId
]
210 self
.cbBlock(self
.getBlockList())
212 def admin(self
, clientId
):
213 if clientId
not in self
._admin
:
214 self
._admin
[clientId
] = self
.getClient(clientId
).copy()
216 self
.cbAdmin(self
.getAdminList())
218 def unAdmin(self
, clientId
):
219 if clientId
in self
._admin
:
220 del self
._admin
[clientId
]
222 self
.cbAdmin(self
.getAdminList())
224 def _getAcl(self
, network
):
225 return self
._acl
.get(network
, (False, False, {}))
227 def _setAcl(self
, network
, ac
, tx
, l
):
228 log
.msg("Changing ACL for %s" % network
)
229 if ac
== tx
== False and len(l
) == 0:
230 log
.msg("Default settings detected")
231 if network
in self
._acl
:
233 del self
._acl
[network
]
235 log
.msg("Setting ACL for %s to %s" % (network
, str((ac
,tx
,l
))))
236 self
._acl
[network
] = (ac
, tx
, l
)
239 def getAcl(self
, network
):
240 ac
, tx
, l
= self
._getAcl
(network
)
243 def getAclFlags(self
, network
):
244 ac
, tx
, l
= self
._getAcl
(network
)
247 def setAclFlags(self
, network
, ac
, tx
):
248 oac
, otx
, l
= self
._getAcl
(network
)
249 self
._setAcl
(network
, ac
, tx
, l
)
251 def addAcl(self
, network
, email
):
252 log
.msg("Adding %s to ACL for %s" % (email
, network
))
253 ac
, tx
, l
= self
._getAcl
(network
)
255 knownUsers
= dict([(x
.EA
, x
) for x
in [y
.user
for y
in self
._clientData
.values()] + self
._mute
.values() + self
._block
.values()])
256 user
= knownUsers
.get(email
, FRNUser(EA
=email
)).copy(ID
=email
, AI
=1)
258 self
._setAcl
(network
, ac
, tx
, l
)
260 def delAcl(self
, network
, email
):
261 log
.msg("Removing %s from ACL for %s" % (email
, network
))
262 ac
, tx
, l
= self
._getAcl
(network
)
265 self
._setAcl
(network
, ac
, tx
, l
)
267 def setAclTx(self
, network
, email
, tx
):
268 oac
, otx
, l
= self
._getAcl
(network
)
274 self
._setAcl
(network
, oac
, otx
, l
)
276 def aclUpdate(self
, user
):
279 ac
, tx
, l
= self
._getAcl
(network
)
282 new
= user
.copy(ID
=email
, AI
=old
.AI
)
284 self
._setAcl
(network
, ac
, tx
, l
)
286 def aclLoginOk(self
, network
, email
):
287 ac
, tx
, l
= self
._getAcl
(network
)
292 def aclTalkOk(self
, network
, email
):
293 ac
, tx
, l
= self
._getAcl
(network
)
298 return l
[email
].AI
== '0'
300 def canLogin(self
, user
):
301 if self
.isBlocked(user
.ID
):
303 return self
.aclLoginOk(user
.NT
, user
.EA
)
305 def canTalk(self
, clientId
):
306 if self
.isMute(clientId
):
308 u
= self
.getClient(clientId
)
309 return self
.aclTalkOk(u
.NT
, u
.EA
)
311 # vim: set et ai sw=4 ts=4 sts=4: