comparison src/server/server.py @ 744:03ccd68a6dab

server side: actionNew now use a dedicated signal handler, which block it if security limit is exceeded
author Goffi <goffi@goffi.org>
date Sun, 22 Nov 2015 21:28:06 +0100
parents 994be887e843
children ad733b670cc3
comparison
equal deleted inserted replaced
743:916075bd0356 744:03ccd68a6dab
982 982
983 def __init__(self, sat_host): 983 def __init__(self, sat_host):
984 Resource.__init__(self) 984 Resource.__init__(self)
985 self.register = None 985 self.register = None
986 self.sat_host = sat_host 986 self.sat_host = sat_host
987 self.signalDeferred = {} 987 self.signalDeferred = {} # dict of deferred (key: profile, value: Deferred)
988 # which manages the long polling HTTP request with signals
988 self.queue = {} 989 self.queue = {}
989 990
990 def plugRegister(self, register): 991 def plugRegister(self, register):
991 self.register = register 992 self.register = register
992 993
1022 function must have profile as last argument""" 1023 function must have profile as last argument"""
1023 def genericCb(*args): 1024 def genericCb(*args):
1024 profile = args[-1] 1025 profile = args[-1]
1025 if not profile in self.sat_host.prof_connected: 1026 if not profile in self.sat_host.prof_connected:
1026 return 1027 return
1027 if profile in self.signalDeferred: 1028 signal_data = (function_name, args[:-1])
1028 self.signalDeferred[profile].callback((function_name, args[:-1])) 1029 try:
1030 signal_callback = self.signalDeferred[profile].callback
1031 except KeyError:
1032 self.queue.setdefault(profile,[]).append(signal_data)
1033 else:
1034 signal_callback(signal_data)
1029 del self.signalDeferred[profile] 1035 del self.signalDeferred[profile]
1030 else:
1031 if profile not in self.queue:
1032 self.queue[profile] = []
1033 self.queue[profile].append((function_name, args[:-1]))
1034 return genericCb 1036 return genericCb
1037
1038 def actionNewHandler(self, action_data, action_id, security_limit, profile):
1039 """actionNew handler
1040
1041 XXX: We need need a dedicated handler has actionNew use a security_limit which must be managed
1042 @param action_data(dict): see bridge documentation
1043 @param action_id(unicode): identitifer of the action
1044 @param security_limit(int): %(doc_security_limit)s
1045 @param profile(unicode): %(doc_profile)s
1046 """
1047 if not profile in self.sat_host.prof_connected:
1048 return
1049 # FIXME: manage security limit in a dedicated method
1050 # raise an exception if it's not OK
1051 # and read value in sat.conf
1052 if security_limit >= C.SECURITY_LIMIT:
1053 log.debug(u"Ignoring action {action_id}, blocked by security limit".format(action_id=action_id))
1054 return
1055 signal_data = ("actionNew", (action_data, action_id, security_limit))
1056 try:
1057 signal_callback = self.signalDeferred[profile].callback
1058 except KeyError:
1059 self.queue.setdefault(profile,[]).append(signal_data)
1060 else:
1061 signal_callback(signal_data)
1062 del self.signalDeferred[profile]
1035 1063
1036 def connected(self, profile, jid_s): 1064 def connected(self, profile, jid_s):
1037 """Connection is done. 1065 """Connection is done.
1038 1066
1039 @param profile (unicode): %(doc_profile)s 1067 @param profile (unicode): %(doc_profile)s
1163 """ 1191 """
1164 profile = ISATSession(request.getSession()).profile 1192 profile = ISATSession(request.getSession()).profile
1165 return ("setAvatar", filepath, profile) 1193 return ("setAvatar", filepath, profile)
1166 1194
1167 1195
1168
1169
1170 class Libervia(service.Service): 1196 class Libervia(service.Service):
1171 1197
1172 1198
1173 def __init__(self, *args, **kwargs): 1199 def __init__(self, *args, **kwargs):
1174 self.initialised = defer.Deferred() 1200 self.initialised = defer.Deferred()
1208 def backendReady(dummy): 1234 def backendReady(dummy):
1209 self.bridge.register("connected", self.signal_handler.connected) 1235 self.bridge.register("connected", self.signal_handler.connected)
1210 self.bridge.register("disconnected", self.signal_handler.disconnected) 1236 self.bridge.register("disconnected", self.signal_handler.disconnected)
1211 self.bridge.register("actionResult", self.action_handler.actionResultCb) 1237 self.bridge.register("actionResult", self.action_handler.actionResultCb)
1212 #core 1238 #core
1213 for signal_name in ['presenceUpdate', 'actionNew', 'newMessage', 'subscribe', 'contactDeleted', 1239 for signal_name in ['presenceUpdate', 'newMessage', 'subscribe', 'contactDeleted',
1214 'newContact', 'entityDataUpdated', 'askConfirmation', 'newAlert', 'paramUpdate']: 1240 'newContact', 'entityDataUpdated', 'askConfirmation', 'newAlert', 'paramUpdate']:
1215 self.bridge.register(signal_name, self.signal_handler.getGenericCb(signal_name)) 1241 self.bridge.register(signal_name, self.signal_handler.getGenericCb(signal_name))
1242 # XXX: actionNew is handled separately because the handler must manage security_limit
1243 self.bridge.register('actionNew', self.signal_handler.actionNewHandler)
1216 #plugins 1244 #plugins
1217 for signal_name in ['psEvent', 'roomJoined', 'roomUserJoined', 'roomUserLeft', 'tarotGameStarted', 'tarotGameNew', 'tarotGameChooseContrat', 1245 for signal_name in ['psEvent', 'roomJoined', 'roomUserJoined', 'roomUserLeft', 'tarotGameStarted', 'tarotGameNew', 'tarotGameChooseContrat',
1218 'tarotGameShowCards', 'tarotGameInvalidCards', 'tarotGameCardsPlayed', 'tarotGameYourTurn', 'tarotGameScore', 'tarotGamePlayers', 1246 'tarotGameShowCards', 'tarotGameInvalidCards', 'tarotGameCardsPlayed', 'tarotGameYourTurn', 'tarotGameScore', 'tarotGamePlayers',
1219 'radiocolStarted', 'radiocolPreload', 'radiocolPlay', 'radiocolNoUpload', 'radiocolUploadOk', 'radiocolSongRejected', 'radiocolPlayers', 1247 'radiocolStarted', 'radiocolPreload', 'radiocolPlay', 'radiocolNoUpload', 'radiocolUploadOk', 'radiocolSongRejected', 'radiocolPlayers',
1220 'roomLeft', 'roomUserChangedNick', 'chatStateReceived']: 1248 'roomLeft', 'roomUserChangedNick', 'chatStateReceived']: