Changeset 150:2f7237d9c537
- Timestamp:
- Aug 15, 2011, 9:35:16 AM (11 years ago)
- Branch:
- wokkel-muc-client-support-24
- Location:
- wokkel
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
wokkel/iwokkel.py
r149 r150 988 988 989 989 990 def kick(roomJID, entityOrNick, reason=None, sender=None):990 def kick(roomJID, nick, reason=None, sender=None): 991 991 """ 992 992 Kick a user from a MUC room. … … 995 995 @type roomJID: L{jid.JID} 996 996 997 @param entityOrNick: The occupant to be banned.998 @type entityOrNick: L{jid.JID} or C{unicode}997 @param nick: The occupant to be banned. 998 @type nick: L{jid.JID} or C{unicode} 999 999 1000 1000 @param reason: The reason given for the kick. -
wokkel/muc.py
r149 r150 107 107 108 108 109 class AdminRequest(xmlstream.IQ): 110 """ 111 A basic admin iq request. 112 113 @ivar method: Type attribute of the IQ request. Either C{'set'} or C{'get'} 114 @type method: C{str} 115 """ 116 117 def __init__(self, xs, method='get'): 118 xmlstream.IQ.__init__(self, xs, method) 119 q = self.addElement((NS_MUC_ADMIN, 'query')) 109 class AdminItem(object): 110 """ 111 Item representing role and/or affiliation for admin request. 112 """ 113 114 def __init__(self, affiliation=None, role=None, entity=None, nick=None, 115 reason=None): 116 self.affiliation = affiliation 117 self.role = role 118 self.entity = entity 119 self.nick = nick 120 self.reason = reason 121 122 123 def toElement(self): 124 element = domish.Element((NS_MUC_ADMIN, 'item')) 125 126 if self.entity: 127 element['jid'] = self.entity.full() 128 129 if self.nick: 130 element['nick'] = self.nick 131 132 if self.affiliation: 133 element['affiliation'] = self.affiliation 134 135 if self.role: 136 element['role'] = self.role 137 138 if self.reason: 139 element.addElement('reason', content=self.reason) 140 141 return element 142 143 144 @classmethod 145 def fromElement(Class, element): 146 item = Class() 147 148 if element.hasAttribute('jid'): 149 item.entity = jid.JID(element['jid']) 150 151 item.nick = element.getAttribute('nick') 152 item.affiliation = element.getAttribute('affiliation') 153 item.role = element.getAttribute('role') 154 155 for child in element.elements(NS_MUC_ADMIN, 'reason'): 156 item.reason = unicode(child) 157 158 return item 159 160 161 162 class AdminStanza(generic.Request): 163 """ 164 An admin request or response. 165 """ 166 167 childParsers = {(NS_MUC_ADMIN, 'query'): '_childParser_query'} 168 169 def toElement(self): 170 element = generic.Request.toElement(self) 171 element.addElement((NS_MUC_ADMIN, 'query')) 172 173 if self.items: 174 for item in self.items: 175 element.query.addChild(item.toElement()) 176 177 return element 178 179 180 def _childParser_query(self, element): 181 self.items = [] 182 for child in element.elements(NS_MUC_ADMIN, 'item'): 183 self.items.append(AdminItem.fromElement(child)) 120 184 121 185 … … 161 225 162 226 return element 163 164 165 166 class AffiliationRequest(AdminRequest):167 """168 Register room request.169 170 @ivar method: Type attribute of the IQ request. Either C{'set'} or C{'get'}171 @type method: C{str}172 173 @ivar affiliation: The affiliation type to send to room.174 @type affiliation: C{str}175 """176 177 def __init__(self, xs, method='get', affiliation='none',178 entityOrNick=None, reason=None):179 AdminRequest.__init__(self, xs, method)180 181 self.affiliation = affiliation182 self.reason = reason183 if entityOrNick:184 self.items([entityOrNick])185 186 def items(self, entities=None):187 """188 Set or Get the items list for this affiliation request.189 """190 if entities:191 for entityOrNick in entities:192 item = self.query.addElement('item')193 item['affiliation'] = self.affiliation194 try:195 item['jid'] = entityOrNick.full()196 except AttributeError:197 item['nick'] = entityOrNick198 199 if self.reason:200 item.addElement('reason', content=self.reason)201 202 return self.query.elements()203 204 205 206 class RoleRequest(AdminRequest):207 def __init__(self, xs, method='get', role='none',208 entityOrNick=None, reason=None):209 AdminRequest.__init__(self, xs, method)210 211 item = self.query.addElement('item')212 item['role'] = role213 try:214 item['jid'] = entityOrNick.full()215 except AttributeError:216 item['nick'] = entityOrNick217 218 if reason:219 item.addElement('reason', content=self.reason)220 227 221 228 … … 1099 1106 Send a request for an affiliation list in a room. 1100 1107 """ 1101 iq = AffiliationRequest(self.xmlstream, 1102 method='get', 1103 affiliation=affiliation, 1104 ) 1105 iq['to'] = roomJID.userhost() 1106 return iq.send() 1108 def cb(response): 1109 stanza = AdminStanza.fromElement(response) 1110 return stanza.items 1111 1112 request = AdminStanza(recipient=roomJID, stanzaType='get') 1113 request.items = [AdminItem(affiliation=affiliation)] 1114 d = self.request(request) 1115 d.addCallback(cb) 1116 return d 1107 1117 1108 1118 1109 1119 def _getRoleList(self, roomJID, role): 1110 1120 """ 1111 Send a role request. 1112 """ 1113 iq = RoleRequest(self.xmlstream, 1114 method='get', 1115 role=role, 1116 ) 1117 iq['to'] = roomJID.full() 1118 return iq.send() 1119 1120 1121 def _setAffiliationList(self, iq, affiliation, occupantJID): 1122 # set a rooms affiliation list 1123 room = self._getRoom(occupantJID) 1124 if room is not None: 1125 affiliation_list = [] 1126 setattr(room, affiliation, []) 1127 1128 for item in iq.query.elements(): 1129 nick = item.getAttribute('nick', None) 1130 entity = item.getAttribute('jid', None) 1131 role = item.getAttribute('role', None) 1132 user = None 1133 if nick is None and entity is None: 1134 raise Exception, 'bad attributes in item list' 1135 if nick is not None: 1136 user = room.getUser(nick) 1137 if user is None: 1138 user = User(nick, entity=jid.internJID(entity)) 1139 user.affiliation = 'member' 1140 if role is not None: 1141 user.role = role 1142 1143 affiliation_list.append(user) 1144 1145 setattr(room, affiliation, affiliation_list) 1146 return room 1121 Send a request for a role list in a room. 1122 """ 1123 def cb(response): 1124 stanza = AdminStanza.fromElement(response) 1125 return stanza.items 1126 1127 request = AdminStanza(recipient=roomJID, stanzaType='get') 1128 request.items = [AdminItem(role=role)] 1129 d = self.request(request) 1130 d.addCallback(cb) 1131 return d 1147 1132 1148 1133 … … 1154 1139 @type roomJID: L{jid.JID} 1155 1140 """ 1156 d = self._getAffiliationList(roomJID, 'member') 1157 d.addCallback(self._setAffiliationList, 'members', roomJID) 1158 return d 1141 return self._getAffiliationList(roomJID, 'member') 1159 1142 1160 1143 … … 1166 1149 @type roomJID: L{jid.JID} 1167 1150 """ 1168 d = self._getAffiliationList(roomJID, 'admin') 1169 d.addCallback(self._setAffiliationList, 'admin', roomJID) 1170 return d 1151 return self._getAffiliationList(roomJID, 'admin') 1171 1152 1172 1153 … … 1178 1159 @type roomJID: L{jid.JID} 1179 1160 """ 1180 d = self._getAffiliationList(roomJID, 'outcast') 1181 d.addCallback(self._setAffiliationList, 'outcast', roomJID) 1182 return d 1161 return self._getAffiliationList(roomJID, 'outcast') 1183 1162 1184 1163 … … 1187 1166 Get an owner list from a room. 1188 1167 1189 @param roomJID: The room jabber/xmpp entity id for the requested member 1190 list. 1191 @type roomJID: L{jid.JID} 1192 """ 1193 d = self._getAffiliationList(roomJID, 'owner') 1194 d.addCallback(self._setAffiliationList, 'owner', roomJID) 1168 @param roomJID: The bare JID of the room. 1169 @type roomJID: L{jid.JID} 1170 """ 1171 return self._getAffiliationList(roomJID, 'owner') 1172 1173 1174 def getModeratorList(self, roomJID): 1175 """ 1176 Get the moderator list of a room. 1177 1178 @param roomJID: The bare JID of the room. 1179 @type roomJID: L{jid.JID} 1180 """ 1181 d = self._getRoleList(roomJID, 'moderator') 1195 1182 return d 1196 1183 … … 1297 1284 1298 1285 1299 def _setAffiliation(self, roomJID, entity OrNick, affiliation,1286 def _setAffiliation(self, roomJID, entity, affiliation, 1300 1287 reason=None, sender=None): 1301 1288 """ 1302 1289 Send a request to change an entity's affiliation to a MUC room. 1303 1290 """ 1304 iq = AffiliationRequest(self.xmlstream, 1305 method='set', 1306 entityOrNick=entityOrNick, 1307 affiliation=affiliation, 1308 reason=reason) 1309 iq['to'] = roomJID.userhost() 1310 if sender is not None: 1311 iq['from'] = unicode(sender) 1312 1313 return iq.send() 1314 1315 1316 def _setRole(self, roomJID, entityOrNick, role, 1291 request = AdminStanza(recipient=roomJID, sender=sender, 1292 stanzaType='set') 1293 item = AdminItem(entity=entity, affiliation=affiliation, reason=reason) 1294 request.items = [item] 1295 return self.request(request) 1296 1297 1298 def _setRole(self, roomJID, nick, role, 1317 1299 reason=None, sender=None): 1318 # send a role request 1319 iq = RoleRequest(self.xmlstream, 1320 method='set', 1321 role=role, 1322 entityOrNick=entityOrNick, 1323 reason=reason) 1324 1325 iq['to'] = roomJID.userhost() 1326 if sender is not None: 1327 iq['from'] = unicode(sender) 1328 return iq.send() 1329 1330 1331 def modifyAffiliationList(self, frm, roomJID, jid_list, affiliation): 1300 """ 1301 Send a request to change an occupant's role in a MUC room. 1302 """ 1303 request = AdminStanza(recipient=roomJID, sender=sender, 1304 stanzaType='set') 1305 item = AdminItem(nick=nick, role=role, reason=reason) 1306 request.items = [item] 1307 return self.request(request) 1308 1309 1310 def modifyAffiliationList(self, roomJID, entities, affiliation, 1311 sender=None): 1332 1312 """ 1333 1313 Modify an affiliation list. 1334 1314 1335 @param frm: The entity sending the request. 1336 @type frm: L{jid.JID} 1337 1338 @param roomJID: The bare JID of the room. 1339 @type roomJID: L{jid.JID} 1340 1341 @param entities: The list of entities to change in a room. This can be 1342 a nick or a full jid. 1343 @type jid_list: L{list} of C{unicode} for nicks. L{list} of L{jid.JID} 1344 for jids. 1345 1346 @param affiliation: The affilation to change. 1315 @param roomJID: The bare JID of the room. 1316 @type roomJID: L{jid.JID} 1317 1318 @param entities: The list of entities to change for a room. 1319 @type entities: L{list} of L{jid.JID} 1320 1321 @param affiliation: The affilation to the entities will acquire. 1347 1322 @type affiliation: C{unicode} 1348 1323 1349 """ 1350 iq = AffiliationRequest(self.xmlstream, 1351 method='set', 1352 affiliation=affiliation, 1353 ) 1354 iq.items(jid_list) 1355 iq['to'] = roomJID.userhost() 1356 iq['from'] = frm.full() 1357 return iq.send() 1324 @param sender: The entity sending the request. 1325 @type sender: L{jid.JID} 1326 1327 """ 1328 request = AdminStanza(recipient=roomJID, sender=sender, 1329 stanzaType='set') 1330 request.items = [AdminItem(entity=entity, affiliation=affiliation) 1331 for entity in entities] 1332 1333 return self.request(request) 1358 1334 1359 1335 … … 1374 1350 @type sender: L{jid.JID} 1375 1351 """ 1376 return self._setRole(roomJID, entityOrNick=nick,1352 return self._setRole(roomJID, nick=nick, 1377 1353 role='participant', 1378 1354 reason=reason, sender=sender) … … 1397 1373 @type sender: L{jid.JID} 1398 1374 """ 1399 return self._setRole(roomJID, entityOrNick=nick, role='visitor',1375 return self._setRole(roomJID, nick=nick, role='visitor', 1400 1376 reason=reason, sender=sender) 1401 1377 … … 1417 1393 @type sender: L{jid.JID} 1418 1394 """ 1419 return self._setRole(roomJID, entityOrNick=nick, role='moderator',1395 return self._setRole(roomJID, nick=nick, role='moderator', 1420 1396 reason=reason, sender=sender) 1421 1397 … … 1441 1417 1442 1418 1443 def kick(self, roomJID, entityOrNick, reason=None, sender=None):1419 def kick(self, roomJID, nick, reason=None, sender=None): 1444 1420 """ 1445 1421 Kick a user from a MUC room. … … 1448 1424 @type roomJID: L{jid.JID} 1449 1425 1450 @param entityOrNick: The occupant to be banned.1451 @type entityOrNick: L{jid.JID} orC{unicode}1426 @param nick: The occupant to be banned. 1427 @type nick: C{unicode} 1452 1428 1453 1429 @param reason: The reason given for the kick. … … 1457 1433 @type sender: L{jid.JID} 1458 1434 """ 1459 return self._set Affiliation(roomJID, entityOrNick, 'none',1460 1435 return self._setRole(roomJID, nick, 'none', 1436 reason=reason, sender=sender) -
wokkel/test/test_muc.py
r148 r150 378 378 self.assertTrue(banned, 'Did not ban user') 379 379 380 d = self.protocol.ban(self. occupantJID, banned, reason='Spam',380 d = self.protocol.ban(self.roomJID, banned, reason='Spam', 381 381 sender=self.userJID) 382 382 d.addCallback(cb) … … 405 405 self.assertTrue(kicked, 'Did not kick user') 406 406 407 d = self.protocol.kick(self. occupantJID, nick, reason='Spam',407 d = self.protocol.kick(self.roomJID, nick, reason='Spam', 408 408 sender=self.userJID) 409 409 d.addCallback(cb) … … 413 413 self.assertTrue(xpath.matches( 414 414 u"/iq[@type='set' and @to='%s']/query/item" 415 "[@ affiliation='none']" % (self.roomJID,),415 "[@role='none']" % (self.roomJID,), 416 416 iq), 417 417 'Wrong kick stanza') … … 800 800 801 801 802 def test_modifyAffiliationList(self): 803 804 entities = [JID('user1@test.example.org'), 805 JID('user2@test.example.org')] 806 d = self.protocol.modifyAffiliationList(self.roomJID, entities, 807 'admin') 808 809 iq = self.stub.output[-1] 810 query = "/iq/query[@xmlns='%s']/item[@xmlns='%s']" % (muc.NS_MUC_ADMIN, 811 muc.NS_MUC_ADMIN) 812 items = xpath.queryForNodes(query, iq) 813 self.assertNotIdentical(None, items) 814 self.assertEquals(entities[0], JID(items[0].getAttribute('jid'))) 815 self.assertEquals('admin', items[0].getAttribute('affiliation')) 816 self.assertEquals(entities[1], JID(items[1].getAttribute('jid'))) 817 self.assertEquals('admin', items[1].getAttribute('affiliation')) 818 819 # Send a response to have the deferred fire. 820 response = toResponse(iq, 'result') 821 self.stub.send(response) 822 return d 823 824 802 825 def test_grantVoice(self): 803 826 """ 804 Test granting voice to a user. 805 827 Granting voice sends request to set role to 'participant'. 806 828 """ 807 829 nick = 'TroubleMaker' … … 809 831 self.assertTrue(give_voice, 'Did not give voice user') 810 832 811 d = self.protocol.grantVoice(self. occupantJID, nick,833 d = self.protocol.grantVoice(self.roomJID, nick, 812 834 sender=self.userJID) 813 835 d.addCallback(cb) … … 817 839 query = (u"/iq[@type='set' and @to='%s']/query/item" 818 840 "[@role='participant']") % self.roomJID 841 self.assertTrue(xpath.matches(query, iq), 'Wrong voice stanza') 842 843 response = toResponse(iq, 'result') 844 self.stub.send(response) 845 return d 846 847 848 def test_revokeVoice(self): 849 """ 850 Revoking voice sends request to set role to 'visitor'. 851 """ 852 nick = 'TroubleMaker' 853 854 d = self.protocol.revokeVoice(self.roomJID, nick, 855 reason="Trouble maker", 856 sender=self.userJID) 857 858 iq = self.stub.output[-1] 859 860 query = (u"/iq[@type='set' and @to='%s']/query/item" 861 "[@role='visitor']") % self.roomJID 862 self.assertTrue(xpath.matches(query, iq), 'Wrong voice stanza') 863 864 response = toResponse(iq, 'result') 865 self.stub.send(response) 866 return d 867 868 869 def test_grantModerator(self): 870 """ 871 Granting moderator privileges sends request to set role to 'moderator'. 872 """ 873 nick = 'TroubleMaker' 874 875 d = self.protocol.grantModerator(self.roomJID, nick, 876 sender=self.userJID) 877 878 iq = self.stub.output[-1] 879 880 query = (u"/iq[@type='set' and @to='%s']/query/item" 881 "[@role='moderator']") % self.roomJID 819 882 self.assertTrue(xpath.matches(query, iq), 'Wrong voice stanza') 820 883 … … 863 926 864 927 def test_getMemberList(self): 865 def cb(room): 866 members = room.members 867 self.assertEquals(1, len(members)) 868 user = members[0] 869 self.assertEquals(JID(u'hag66@shakespeare.lit'), user.entity) 870 self.assertEquals(u'thirdwitch', user.nick) 871 self.assertEquals(u'participant', user.role) 872 873 self._createRoom() 928 """ 929 Retrieving the member list returns a list of L{muc.AdminItem}s 930 931 The request asks for the affiliation C{'member'}. 932 """ 933 def cb(items): 934 self.assertEquals(1, len(items)) 935 item = items[0] 936 self.assertEquals(JID(u'hag66@shakespeare.lit'), item.entity) 937 self.assertEquals(u'thirdwitch', item.nick) 938 self.assertEquals(u'member', item.affiliation) 939 874 940 d = self.protocol.getMemberList(self.roomJID) 875 941 d.addCallback(cb) 876 942 877 943 iq = self.stub.output[-1] 878 query = iq.query 879 self.assertNotIdentical(None, query) 880 self.assertEquals(NS_MUC_ADMIN, query.uri) 944 self.assertEquals('get', iq.getAttribute('type')) 945 query = "/iq/query[@xmlns='%s']/item[@xmlns='%s']" % (muc.NS_MUC_ADMIN, 946 muc.NS_MUC_ADMIN) 947 items = xpath.queryForNodes(query, iq) 948 self.assertNotIdentical(None, items) 949 self.assertEquals(1, len(items)) 950 self.assertEquals('member', items[0].getAttribute('affiliation')) 881 951 882 952 response = toResponse(iq, 'result') … … 890 960 891 961 return d 962 963 964 def test_getAdminList(self): 965 """ 966 Retrieving the admin list returns a list of L{muc.AdminItem}s 967 968 The request asks for the affiliation C{'admin'}. 969 """ 970 d = self.protocol.getAdminList(self.roomJID) 971 972 iq = self.stub.output[-1] 973 query = "/iq/query[@xmlns='%s']/item[@xmlns='%s']" % (muc.NS_MUC_ADMIN, 974 muc.NS_MUC_ADMIN) 975 items = xpath.queryForNodes(query, iq) 976 self.assertEquals('admin', items[0].getAttribute('affiliation')) 977 978 response = toResponse(iq, 'result') 979 query = response.addElement((NS_MUC_ADMIN, 'query')) 980 self.stub.send(response) 981 982 return d 983 984 985 def test_getBanList(self): 986 """ 987 Retrieving the ban list returns a list of L{muc.AdminItem}s 988 989 The request asks for the affiliation C{'outcast'}. 990 """ 991 def cb(items): 992 self.assertEquals(1, len(items)) 993 item = items[0] 994 self.assertEquals(JID(u'hag66@shakespeare.lit'), item.entity) 995 self.assertEquals(u'outcast', item.affiliation) 996 self.assertEquals(u'Trouble making', item.reason) 997 998 d = self.protocol.getBanList(self.roomJID) 999 d.addCallback(cb) 1000 1001 iq = self.stub.output[-1] 1002 query = "/iq/query[@xmlns='%s']/item[@xmlns='%s']" % (muc.NS_MUC_ADMIN, 1003 muc.NS_MUC_ADMIN) 1004 items = xpath.queryForNodes(query, iq) 1005 self.assertEquals('outcast', items[0].getAttribute('affiliation')) 1006 1007 response = toResponse(iq, 'result') 1008 query = response.addElement((NS_MUC_ADMIN, 'query')) 1009 item = query.addElement('item') 1010 item['affiliation'] ='outcast' 1011 item['jid'] = 'hag66@shakespeare.lit' 1012 item.addElement('reason', content='Trouble making') 1013 self.stub.send(response) 1014 1015 return d 1016 1017 1018 def test_getOwnerList(self): 1019 """ 1020 Retrieving the owner list returns a list of L{muc.AdminItem}s 1021 1022 The request asks for the affiliation C{'owner'}. 1023 """ 1024 d = self.protocol.getOwnerList(self.roomJID) 1025 1026 iq = self.stub.output[-1] 1027 query = "/iq/query[@xmlns='%s']/item[@xmlns='%s']" % (muc.NS_MUC_ADMIN, 1028 muc.NS_MUC_ADMIN) 1029 items = xpath.queryForNodes(query, iq) 1030 self.assertEquals('owner', items[0].getAttribute('affiliation')) 1031 1032 response = toResponse(iq, 'result') 1033 query = response.addElement((NS_MUC_ADMIN, 'query')) 1034 self.stub.send(response) 1035 1036 return d 1037 1038 1039 def test_getModeratorList(self): 1040 """ 1041 Retrieving the moderator returns a list of L{muc.AdminItem}s. 1042 1043 The request asks for the role C{'moderator'}. 1044 """ 1045 1046 def cb(items): 1047 self.assertEquals(1, len(items)) 1048 item = items[0] 1049 self.assertEquals(JID(u'hag66@shakespeare.lit'), item.entity) 1050 self.assertEquals(u'thirdwitch', item.nick) 1051 self.assertEquals(u'moderator', item.role) 1052 1053 d = self.protocol.getModeratorList(self.roomJID) 1054 d.addCallback(cb) 1055 1056 iq = self.stub.output[-1] 1057 self.assertEquals('get', iq.getAttribute('type')) 1058 query = "/iq/query[@xmlns='%s']/item[@xmlns='%s']" % (muc.NS_MUC_ADMIN, 1059 muc.NS_MUC_ADMIN) 1060 items = xpath.queryForNodes(query, iq) 1061 self.assertNotIdentical(None, items) 1062 self.assertEquals(1, len(items)) 1063 self.assertEquals('moderator', items[0].getAttribute('role')) 1064 1065 response = toResponse(iq, 'result') 1066 query = response.addElement((NS_MUC_ADMIN, 'query')) 1067 item = query.addElement('item') 1068 item['affiliation'] ='member' 1069 item['jid'] = 'hag66@shakespeare.lit' 1070 item['nick'] = 'thirdwitch' 1071 item['role'] = 'moderator' 1072 self.stub.send(response) 1073 1074 return d
Note: See TracChangeset
for help on using the changeset viewer.