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
|
# Copyright (C) 2018 Philipp Hörist <philipp AT hoerist.com>
#
# This file is part of nbxmpp.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; If not, see <http://www.gnu.org/licenses/>.
import logging
from nbxmpp.protocol import NS_CARBONS
from nbxmpp.protocol import NS_FORWARD
from nbxmpp.protocol import NS_MUC_USER
from nbxmpp.protocol import NS_MAM_1
from nbxmpp.protocol import NS_MAM_2
from nbxmpp.protocol import NodeProcessed
from nbxmpp.protocol import InvalidFrom
from nbxmpp.protocol import InvalidStanza
from nbxmpp.protocol import Message
from nbxmpp.structs import MAMData
from nbxmpp.structs import CarbonData
from nbxmpp.modules.delay import parse_delay
log = logging.getLogger('nbxmpp.m.misc')
def unwrap_carbon(stanza, own_jid):
carbon = stanza.getTag('received', namespace=NS_CARBONS)
if carbon is None:
carbon = stanza.getTag('sent', namespace=NS_CARBONS)
if carbon is None:
return stanza, None
# Carbon must be from our bare jid
if not stanza.getFrom() == own_jid.getBare():
raise InvalidFrom('Invalid from: %s' % stanza.getAttr('from'))
forwarded = carbon.getTag('forwarded', namespace=NS_FORWARD)
message = Message(node=forwarded.getTag('message'))
type_ = carbon.getName()
# Fill missing to/from
to = message.getTo()
if to is None:
message.setTo(own_jid.getBare())
frm = message.getFrom()
if frm is None:
message.setFrom(own_jid.getBare())
if type_ == 'received':
if message.getFrom().bareMatch(own_jid):
# Drop 'received' Carbons from ourself, we already
# got the message with the 'sent' Carbon or via the
# message itself
raise NodeProcessed('Drop "received"-Carbon from ourself')
if message.getTag('x', namespace=NS_MUC_USER) is not None:
# A MUC broadcasts messages sent to us to all resources
# there is no need to process the received carbon
raise NodeProcessed('Drop MUC-PM "received"-Carbon')
return message, CarbonData(type=type_)
def unwrap_mam(stanza, own_jid):
result = stanza.getTag('result', namespace=NS_MAM_2)
if result is None:
result = stanza.getTag('result', namespace=NS_MAM_1)
if result is None:
return stanza, None
query_id = result.getAttr('queryid')
if query_id is None:
log.warning('No queryid on MAM message')
log.warning(stanza)
raise InvalidStanza
id_ = result.getAttr('id')
if id_ is None:
log.warning('No id on MAM message')
log.warning(stanza)
raise InvalidStanza
forwarded = result.getTag('forwarded', namespace=NS_FORWARD)
message = Message(node=forwarded.getTag('message'))
# Fill missing to/from
to = message.getTo()
if to is None:
message.setTo(own_jid.getBare())
frm = message.getFrom()
if frm is None:
message.setFrom(own_jid.getBare())
# Timestamp parsing
# Most servers dont set the 'from' attr, so we cant check for it
delay_timestamp = parse_delay(forwarded)
if delay_timestamp is None:
log.warning('No timestamp on MAM message')
log.warning(stanza)
raise InvalidStanza
return message, MAMData(id=id_,
query_id=query_id,
archive=stanza.getFrom(),
namespace=result.getNamespace(),
timestamp=delay_timestamp)
|