annotate libervia/web/pages/_browser/jid.py @ 1543:f00497c00e38

pages (chat): fix `own_jid` exposure: `own_jid` is a `JID` instance, and must be casted to str to be exposed.
author Goffi <goffi@goffi.org>
date Thu, 06 Jul 2023 12:05:48 +0200
parents b338c31d5251
children 7006b55001a4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1530
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python3
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
2
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
3 # Libervia XMPP
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
4 # Copyright (C) 2009-2023 Jérôme Poisson (goffi@goffi.org)
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
5
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
6 # This program is free software: you can redistribute it and/or modify
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # it under the terms of the GNU Affero General Public License as published by
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # the Free Software Foundation, either version 3 of the License, or
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # (at your option) any later version.
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
10
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
11 # This program is distributed in the hope that it will be useful,
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # GNU Affero General Public License for more details.
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
15
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
16 # You should have received a copy of the GNU Affero General Public License
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
18
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
19 # XXX: this is the same `jid` class as in `libervia.frontends.tools`, but typing hints
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
20 # have been removed as they are a bit slow to load with Brython, and this class is used
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
21 # a lot.
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
22
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
23
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
24 class JID(str):
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
25 """This class helps manage JID (<local>@<domain>/<resource>)"""
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
26
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
27 def __new__(cls, jid_str: str) -> "JID":
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
28 return str.__new__(cls, cls._normalize(jid_str))
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
29
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
30 def __init__(self, jid_str: str):
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
31 self._node, self._domain, self._resource = self._parse()
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
32
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
33 @staticmethod
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
34 def _normalize(jid_str: str) -> str:
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
35 """Naive normalization before instantiating and parsing the JID"""
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
36 if not jid_str:
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
37 return jid_str
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
38 tokens = jid_str.split("/")
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
39 tokens[0] = tokens[0].lower() # force node and domain to lower-case
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
40 return "/".join(tokens)
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
41
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
42 def _parse(self):
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
43 """Find node, domain, and resource from JID"""
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
44 node_end = self.find("@")
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
45 if node_end < 0:
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
46 node_end = 0
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
47 domain_end = self.find("/")
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
48 if domain_end == 0:
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
49 raise ValueError("a jid can't start with '/'")
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
50 if domain_end == -1:
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
51 domain_end = len(self)
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
52 node = self[:node_end] or None
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
53 domain = self[(node_end + 1) if node_end else 0 : domain_end]
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
54 resource = self[domain_end + 1 :] or None
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
55 return node, domain, resource
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
56
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
57 @property
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
58 def node(self):
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
59 return self._node
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
60
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
61 @property
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
62 def local(self):
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
63 return self._node
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
64
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
65 @property
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
66 def domain(self) -> str:
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
67 return self._domain
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
68
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
69 @property
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
70 def resource(self):
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
71 return self._resource
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
72
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
73 @property
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
74 def bare(self) -> "JID":
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
75 if not self.node:
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
76 return JID(self.domain)
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
77 return JID(f"{self.node}@{self.domain}")
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
78
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
79 def change_resource(self, resource: str) -> "JID":
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
80 """Build a new JID with the same node and domain but a different resource.
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
81
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
82 @param resource: The new resource for the JID.
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
83 @return: A new JID instance with the updated resource.
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
84 """
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
85 return JID(f"{self.bare}/{resource}")
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
86
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
87 def is_valid(self) -> bool:
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
88 """
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
89 @return: True if the JID is XMPP compliant
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
90 """
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
91 # Simple check for domain part
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
92 if not self.domain or self.domain.startswith(".") or self.domain.endswith("."):
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
93 return False
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
94 if ".." in self.domain:
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
95 return False
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
96 return True
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
97
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
98
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
99 def new_resource(entity: JID, resource: str) -> JID:
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
100 """Build a new JID from the given entity and resource.
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
101
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
102 @param entity: original JID
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
103 @param resource: new resource
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
104 @return: a new JID instance
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
105 """
b338c31d5251 browser: integrate the `jid` module
Goffi <goffi@goffi.org>
parents:
diff changeset
106 return entity.change_resource(resource)